mirror of https://gitee.com/openkylin/linux.git
141 lines
2.6 KiB
ArmAsm
141 lines
2.6 KiB
ArmAsm
/*
|
|
* PowerNV OPAL takeover assembly code, for use by prom_init.c
|
|
*
|
|
* Copyright 2011 IBM Corp.
|
|
*
|
|
* 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 <asm/ppc_asm.h>
|
|
#include <asm/hvcall.h>
|
|
#include <asm/asm-offsets.h>
|
|
#include <asm/opal.h>
|
|
|
|
#define STK_PARAM(i) (48 + ((i)-3)*8)
|
|
|
|
#define H_HAL_TAKEOVER 0x5124
|
|
#define H_HAL_TAKEOVER_QUERY_MAGIC -1
|
|
|
|
.text
|
|
_GLOBAL(opal_query_takeover)
|
|
mfcr r0
|
|
stw r0,8(r1)
|
|
std r3,STK_PARAM(r3)(r1)
|
|
std r4,STK_PARAM(r4)(r1)
|
|
li r3,H_HAL_TAKEOVER
|
|
li r4,H_HAL_TAKEOVER_QUERY_MAGIC
|
|
HVSC
|
|
ld r10,STK_PARAM(r3)(r1)
|
|
std r4,0(r10)
|
|
ld r10,STK_PARAM(r4)(r1)
|
|
std r5,0(r10)
|
|
lwz r0,8(r1)
|
|
mtcrf 0xff,r0
|
|
blr
|
|
|
|
_GLOBAL(opal_do_takeover)
|
|
mfcr r0
|
|
stw r0,8(r1)
|
|
mflr r0
|
|
std r0,16(r1)
|
|
bl __opal_do_takeover
|
|
ld r0,16(r1)
|
|
mtlr r0
|
|
lwz r0,8(r1)
|
|
mtcrf 0xff,r0
|
|
blr
|
|
|
|
__opal_do_takeover:
|
|
ld r4,0(r3)
|
|
ld r5,0x8(r3)
|
|
ld r6,0x10(r3)
|
|
ld r7,0x18(r3)
|
|
ld r8,0x20(r3)
|
|
ld r9,0x28(r3)
|
|
ld r10,0x30(r3)
|
|
ld r11,0x38(r3)
|
|
li r3,H_HAL_TAKEOVER
|
|
HVSC
|
|
blr
|
|
|
|
.globl opal_secondary_entry
|
|
opal_secondary_entry:
|
|
mr r31,r3
|
|
mfmsr r11
|
|
li r12,(MSR_SF | MSR_ISF)@highest
|
|
sldi r12,r12,48
|
|
or r11,r11,r12
|
|
mtmsrd r11
|
|
isync
|
|
mfspr r4,SPRN_PIR
|
|
std r4,0(r3)
|
|
1: HMT_LOW
|
|
ld r4,8(r3)
|
|
cmpli cr0,r4,0
|
|
beq 1b
|
|
HMT_MEDIUM
|
|
1: addi r3,r31,16
|
|
bl __opal_do_takeover
|
|
b 1b
|
|
|
|
_GLOBAL(opal_enter_rtas)
|
|
mflr r0
|
|
std r0,16(r1)
|
|
stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
|
|
|
|
/* Because PROM is running in 32b mode, it clobbers the high order half
|
|
* of all registers that it saves. We therefore save those registers
|
|
* PROM might touch to the stack. (r0, r3-r13 are caller saved)
|
|
*/
|
|
SAVE_GPR(2, r1)
|
|
SAVE_GPR(13, r1)
|
|
SAVE_8GPRS(14, r1)
|
|
SAVE_10GPRS(22, r1)
|
|
mfcr r10
|
|
mfmsr r11
|
|
std r10,_CCR(r1)
|
|
std r11,_MSR(r1)
|
|
|
|
/* Get the PROM entrypoint */
|
|
mtlr r5
|
|
|
|
/* Switch MSR to 32 bits mode
|
|
*/
|
|
li r12,1
|
|
rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
|
|
andc r11,r11,r12
|
|
li r12,1
|
|
rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
|
|
andc r11,r11,r12
|
|
mtmsrd r11
|
|
isync
|
|
|
|
/* Enter RTAS here... */
|
|
blrl
|
|
|
|
/* Just make sure that r1 top 32 bits didn't get
|
|
* corrupt by OF
|
|
*/
|
|
rldicl r1,r1,0,32
|
|
|
|
/* Restore the MSR (back to 64 bits) */
|
|
ld r0,_MSR(r1)
|
|
MTMSRD(r0)
|
|
isync
|
|
|
|
/* Restore other registers */
|
|
REST_GPR(2, r1)
|
|
REST_GPR(13, r1)
|
|
REST_8GPRS(14, r1)
|
|
REST_10GPRS(22, r1)
|
|
ld r4,_CCR(r1)
|
|
mtcr r4
|
|
|
|
addi r1,r1,PROM_FRAME_SIZE
|
|
ld r0,16(r1)
|
|
mtlr r0
|
|
blr
|