mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-04 20:19:47 +08:00 
			
		
		
		
	 a1ff57416a
			
		
	
	
		a1ff57416a
		
	
	
	
	
		
			
			When configured with CONFIG_PPC_EARLY_DEBUG_OPAL=y the kernel expects
the OPAL entry and base addresses to be passed in r8 and r9
respectively. Currently the wrapper does not attempt to restore these
values before entering the decompressed kernel which causes the kernel
to branch into whatever happens to be in r9 when doing a write to the
OPAL console in early boot.
This patch adds a platform_ops hook that can be used to branch into the
new kernel. The OPAL console driver patches this at runtime so that if
the console is used it will be restored just prior to entering the
kernel.
Fixes: 656ad58ef1 ("powerpc/boot: Add OPAL console to epapr wrappers")
Cc: stable@vger.kernel.org # v4.8+
Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
		
	
			
		
			
				
	
	
		
			72 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2016 IBM Corporation.
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU General Public License
 | |
|  * as published by the Free Software Foundation; either version
 | |
|  * 2 of the License, or (at your option) any later version.
 | |
|  */
 | |
| 
 | |
| #include "ppc_asm.h"
 | |
| #include "../include/asm/opal-api.h"
 | |
| 
 | |
| 	.text
 | |
| 
 | |
| 	.globl opal_kentry
 | |
| opal_kentry:
 | |
| 	/* r3 is the fdt ptr */
 | |
| 	mtctr r4
 | |
| 	li	r4, 0
 | |
| 	li	r5, 0
 | |
| 	li	r6, 0
 | |
| 	li	r7, 0
 | |
| 	ld	r11,opal@got(r2)
 | |
| 	ld	r8,0(r11)
 | |
| 	ld	r9,8(r11)
 | |
| 	bctr
 | |
| 
 | |
| #define OPAL_CALL(name, token)				\
 | |
| 	.globl name;					\
 | |
| name:							\
 | |
| 	li	r0, token;				\
 | |
| 	b	opal_call;
 | |
| 
 | |
| opal_call:
 | |
| 	mflr	r11
 | |
| 	std	r11,16(r1)
 | |
| 	mfcr	r12
 | |
| 	stw	r12,8(r1)
 | |
| 	mr	r13,r2
 | |
| 
 | |
| 	/* Set opal return address */
 | |
| 	ld	r11,opal_return@got(r2)
 | |
| 	mtlr	r11
 | |
| 	mfmsr	r12
 | |
| 
 | |
| 	/* switch to BE when we enter OPAL */
 | |
| 	li	r11,MSR_LE
 | |
| 	andc	r12,r12,r11
 | |
| 	mtspr	SPRN_HSRR1,r12
 | |
| 
 | |
| 	/* load the opal call entry point and base */
 | |
| 	ld	r11,opal@got(r2)
 | |
| 	ld	r12,8(r11)
 | |
| 	ld	r2,0(r11)
 | |
| 	mtspr	SPRN_HSRR0,r12
 | |
| 	hrfid
 | |
| 
 | |
| opal_return:
 | |
| 	FIXUP_ENDIAN
 | |
| 	mr	r2,r13;
 | |
| 	lwz	r11,8(r1);
 | |
| 	ld	r12,16(r1)
 | |
| 	mtcr	r11;
 | |
| 	mtlr	r12
 | |
| 	blr
 | |
| 
 | |
| OPAL_CALL(opal_console_write,			OPAL_CONSOLE_WRITE);
 | |
| OPAL_CALL(opal_console_read,			OPAL_CONSOLE_READ);
 | |
| OPAL_CALL(opal_console_write_buffer_space,	OPAL_CONSOLE_WRITE_BUFFER_SPACE);
 | |
| OPAL_CALL(opal_poll_events,			OPAL_POLL_EVENTS);
 | |
| OPAL_CALL(opal_console_flush,			OPAL_CONSOLE_FLUSH);
 |