114a43e69SBenjamin Herrenschmidt/*
214a43e69SBenjamin Herrenschmidt * PowerNV OPAL API wrappers
314a43e69SBenjamin Herrenschmidt *
414a43e69SBenjamin Herrenschmidt * Copyright 2011 IBM Corp.
514a43e69SBenjamin Herrenschmidt *
614a43e69SBenjamin Herrenschmidt * This program is free software; you can redistribute it and/or
714a43e69SBenjamin Herrenschmidt * modify it under the terms of the GNU General Public License
814a43e69SBenjamin Herrenschmidt * as published by the Free Software Foundation; either version
914a43e69SBenjamin Herrenschmidt * 2 of the License, or (at your option) any later version.
1014a43e69SBenjamin Herrenschmidt */
1114a43e69SBenjamin Herrenschmidt
1258995a9aSAnton Blanchard#include <linux/jump_label.h>
1314a43e69SBenjamin Herrenschmidt#include <asm/ppc_asm.h>
1414a43e69SBenjamin Herrenschmidt#include <asm/hvcall.h>
1514a43e69SBenjamin Herrenschmidt#include <asm/asm-offsets.h>
1614a43e69SBenjamin Herrenschmidt#include <asm/opal.h>
17ec0c464cSChristophe Leroy#include <asm/asm-compat.h>
182c86cd18SChristophe Leroy#include <asm/feature-fixups.h>
19c49f6353SAnton Blanchard
20c49f6353SAnton Blanchard	.section ".text"
21c49f6353SAnton Blanchard
22c49f6353SAnton Blanchard/*
2375d9fc7fSNicholas Piggin * r3-r10		- OPAL call arguments
2475d9fc7fSNicholas Piggin * STK_PARAM(R11)	- OPAL opcode
2575d9fc7fSNicholas Piggin * STK_PARAM(R12)	- MSR to restore
26c49f6353SAnton Blanchard */
2775d9fc7fSNicholas Piggin_GLOBAL_TOC(__opal_call)
2875d9fc7fSNicholas Piggin	mflr	r0
2975d9fc7fSNicholas Piggin	std	r0,PPC_LR_STKOFF(r1)
3075d9fc7fSNicholas Piggin	ld	r12,STK_PARAM(R12)(r1)
3175d9fc7fSNicholas Piggin	li	r0,MSR_IR|MSR_DR|MSR_LE
3275d9fc7fSNicholas Piggin	andc	r12,r12,r0
3375d9fc7fSNicholas Piggin	LOAD_REG_ADDR(r11, opal_return)
3475d9fc7fSNicholas Piggin	mtlr	r11
3575d9fc7fSNicholas Piggin	LOAD_REG_ADDR(r11, opal)
3675d9fc7fSNicholas Piggin	ld	r2,0(r11)
3775d9fc7fSNicholas Piggin	ld	r11,8(r11)
3875d9fc7fSNicholas Piggin	mtspr	SPRN_HSRR0,r11
3975d9fc7fSNicholas Piggin	mtspr	SPRN_HSRR1,r12
4075d9fc7fSNicholas Piggin	/* set token to r0 */
4175d9fc7fSNicholas Piggin	ld	r0,STK_PARAM(R11)(r1)
4214a43e69SBenjamin Herrenschmidt	hrfid
43ad0289e4SAnton Blanchardopal_return:
44be401b37SBenjamin Herrenschmidt	/*
4575d9fc7fSNicholas Piggin	 * Restore MSR on OPAL return. The MSR is set to big-endian.
46be401b37SBenjamin Herrenschmidt	 */
4775d9fc7fSNicholas Piggin#ifdef __BIG_ENDIAN__
4875d9fc7fSNicholas Piggin	ld	r11,STK_PARAM(R12)(r1)
4975d9fc7fSNicholas Piggin	mtmsrd	r11
5075d9fc7fSNicholas Piggin#else
5175d9fc7fSNicholas Piggin	/* Endian can only be switched with rfi, must byte reverse MSR load */
5275d9fc7fSNicholas Piggin	.short 0x4039	 /* li r10,STK_PARAM(R12)		*/
5375d9fc7fSNicholas Piggin	.byte (STK_PARAM(R12) >> 8) & 0xff
5475d9fc7fSNicholas Piggin	.byte STK_PARAM(R12) & 0xff
5514a43e69SBenjamin Herrenschmidt
5675d9fc7fSNicholas Piggin	.long 0x280c6a7d /* ldbrx r11,r10,r1			*/
5775d9fc7fSNicholas Piggin	.long 0x05009f42 /* bcl 20,31,$+4			*/
5875d9fc7fSNicholas Piggin	.long 0xa602487d /* mflr r10				*/
5975d9fc7fSNicholas Piggin	.long 0x14004a39 /* addi r10,r10,20			*/
6075d9fc7fSNicholas Piggin	.long 0xa64b5a7d /* mthsrr0 r10				*/
6175d9fc7fSNicholas Piggin	.long 0xa64b7b7d /* mthsrr1 r11				*/
6275d9fc7fSNicholas Piggin	.long 0x2402004c /* hrfid				*/
6375d9fc7fSNicholas Piggin#endif
6475d9fc7fSNicholas Piggin	ld	r2,PACATOC(r13)
6575d9fc7fSNicholas Piggin	ld	r0,PPC_LR_STKOFF(r1)
66c49f6353SAnton Blanchard	mtlr	r0
67c49f6353SAnton Blanchard	blr
68