123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- /*
- * 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
|