1/* 2 * PowerNV OPAL takeover assembly code, for use by prom_init.c 3 * 4 * Copyright 2011 IBM Corp. 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#include <asm/ppc_asm.h> 13#include <asm/hvcall.h> 14#include <asm/asm-offsets.h> 15#include <asm/opal.h> 16 17#define STK_PARAM(i) (48 + ((i)-3)*8) 18 19#define H_HAL_TAKEOVER 0x5124 20#define H_HAL_TAKEOVER_QUERY_MAGIC -1 21 22 .text 23_GLOBAL(opal_query_takeover) 24 mfcr r0 25 stw r0,8(r1) 26 std r3,STK_PARAM(r3)(r1) 27 std r4,STK_PARAM(r4)(r1) 28 li r3,H_HAL_TAKEOVER 29 li r4,H_HAL_TAKEOVER_QUERY_MAGIC 30 HVSC 31 ld r10,STK_PARAM(r3)(r1) 32 std r4,0(r10) 33 ld r10,STK_PARAM(r4)(r1) 34 std r5,0(r10) 35 lwz r0,8(r1) 36 mtcrf 0xff,r0 37 blr 38 39_GLOBAL(opal_do_takeover) 40 mfcr r0 41 stw r0,8(r1) 42 mflr r0 43 std r0,16(r1) 44 bl __opal_do_takeover 45 ld r0,16(r1) 46 mtlr r0 47 lwz r0,8(r1) 48 mtcrf 0xff,r0 49 blr 50 51__opal_do_takeover: 52 ld r4,0(r3) 53 ld r5,0x8(r3) 54 ld r6,0x10(r3) 55 ld r7,0x18(r3) 56 ld r8,0x20(r3) 57 ld r9,0x28(r3) 58 ld r10,0x30(r3) 59 ld r11,0x38(r3) 60 li r3,H_HAL_TAKEOVER 61 HVSC 62 blr 63 64 .globl opal_secondary_entry 65opal_secondary_entry: 66 mr r31,r3 67 mfmsr r11 68 li r12,(MSR_SF | MSR_ISF)@highest 69 sldi r12,r12,48 70 or r11,r11,r12 71 mtmsrd r11 72 isync 73 mfspr r4,SPRN_PIR 74 std r4,0(r3) 751: HMT_LOW 76 ld r4,8(r3) 77 cmpli cr0,r4,0 78 beq 1b 79 HMT_MEDIUM 801: addi r3,r31,16 81 bl __opal_do_takeover 82 b 1b 83 84_GLOBAL(opal_enter_rtas) 85 mflr r0 86 std r0,16(r1) 87 stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ 88 89 /* Because PROM is running in 32b mode, it clobbers the high order half 90 * of all registers that it saves. We therefore save those registers 91 * PROM might touch to the stack. (r0, r3-r13 are caller saved) 92 */ 93 SAVE_GPR(2, r1) 94 SAVE_GPR(13, r1) 95 SAVE_8GPRS(14, r1) 96 SAVE_10GPRS(22, r1) 97 mfcr r10 98 mfmsr r11 99 std r10,_CCR(r1) 100 std r11,_MSR(r1) 101 102 /* Get the PROM entrypoint */ 103 mtlr r5 104 105 /* Switch MSR to 32 bits mode 106 */ 107 li r12,1 108 rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) 109 andc r11,r11,r12 110 li r12,1 111 rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) 112 andc r11,r11,r12 113 mtmsrd r11 114 isync 115 116 /* Enter RTAS here... */ 117 blrl 118 119 /* Just make sure that r1 top 32 bits didn't get 120 * corrupt by OF 121 */ 122 rldicl r1,r1,0,32 123 124 /* Restore the MSR (back to 64 bits) */ 125 ld r0,_MSR(r1) 126 MTMSRD(r0) 127 isync 128 129 /* Restore other registers */ 130 REST_GPR(2, r1) 131 REST_GPR(13, r1) 132 REST_8GPRS(14, r1) 133 REST_10GPRS(22, r1) 134 ld r4,_CCR(r1) 135 mtcr r4 136 137 addi r1,r1,PROM_FRAME_SIZE 138 ld r0,16(r1) 139 mtlr r0 140 blr 141