aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/boot/main.c8
-rw-r--r--arch/powerpc/boot/opal-calls.S13
-rw-r--r--arch/powerpc/boot/opal.c11
-rw-r--r--arch/powerpc/boot/ops.h1
4 files changed, 31 insertions, 2 deletions
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index 57d42d129033..78aaf4ffd7ab 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -232,8 +232,12 @@ void start(void)
232 console_ops.close(); 232 console_ops.close();
233 233
234 kentry = (kernel_entry_t) vmlinux.addr; 234 kentry = (kernel_entry_t) vmlinux.addr;
235 if (ft_addr) 235 if (ft_addr) {
236 kentry(ft_addr, 0, NULL); 236 if(platform_ops.kentry)
237 platform_ops.kentry(ft_addr, vmlinux.addr);
238 else
239 kentry(ft_addr, 0, NULL);
240 }
237 else 241 else
238 kentry((unsigned long)initrd.addr, initrd.size, 242 kentry((unsigned long)initrd.addr, initrd.size,
239 loader_info.promptr); 243 loader_info.promptr);
diff --git a/arch/powerpc/boot/opal-calls.S b/arch/powerpc/boot/opal-calls.S
index ff2f1b97bc53..2a99fc9a3ccf 100644
--- a/arch/powerpc/boot/opal-calls.S
+++ b/arch/powerpc/boot/opal-calls.S
@@ -12,6 +12,19 @@
12 12
13 .text 13 .text
14 14
15 .globl opal_kentry
16opal_kentry:
17 /* r3 is the fdt ptr */
18 mtctr r4
19 li r4, 0
20 li r5, 0
21 li r6, 0
22 li r7, 0
23 ld r11,opal@got(r2)
24 ld r8,0(r11)
25 ld r9,8(r11)
26 bctr
27
15#define OPAL_CALL(name, token) \ 28#define OPAL_CALL(name, token) \
16 .globl name; \ 29 .globl name; \
17name: \ 30name: \
diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
index 1f37e1c1d6d8..d7b4fd47eb44 100644
--- a/arch/powerpc/boot/opal.c
+++ b/arch/powerpc/boot/opal.c
@@ -23,14 +23,25 @@ struct opal {
23 23
24static u32 opal_con_id; 24static u32 opal_con_id;
25 25
26/* see opal-wrappers.S */
26int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer); 27int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer);
27int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer); 28int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer);
28int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length); 29int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length);
29int64_t opal_console_flush(uint64_t term_number); 30int64_t opal_console_flush(uint64_t term_number);
30int64_t opal_poll_events(uint64_t *outstanding_event_mask); 31int64_t opal_poll_events(uint64_t *outstanding_event_mask);
31 32
33void opal_kentry(unsigned long fdt_addr, void *vmlinux_addr);
34
32static int opal_con_open(void) 35static int opal_con_open(void)
33{ 36{
37 /*
38 * When OPAL loads the boot kernel it stashes the OPAL base and entry
39 * address in r8 and r9 so the kernel can use the OPAL console
40 * before unflattening the devicetree. While executing the wrapper will
41 * probably trash r8 and r9 so this kentry hook restores them before
42 * entering the decompressed kernel.
43 */
44 platform_ops.kentry = opal_kentry;
34 return 0; 45 return 0;
35} 46}
36 47
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 309d1b127e96..fad1862f4b2d 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -30,6 +30,7 @@ struct platform_ops {
30 void * (*realloc)(void *ptr, unsigned long size); 30 void * (*realloc)(void *ptr, unsigned long size);
31 void (*exit)(void); 31 void (*exit)(void);
32 void * (*vmlinux_alloc)(unsigned long size); 32 void * (*vmlinux_alloc)(unsigned long size);
33 void (*kentry)(unsigned long fdt_addr, void *vmlinux_addr);
33}; 34};
34extern struct platform_ops platform_ops; 35extern struct platform_ops platform_ops;
35 36