Benjamin Herrenschmidt | 27f4488 | 2011-09-19 18:27:58 +0000 | [diff] [blame] | 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 | |
Benjamin Herrenschmidt | 27f4488 | 2011-09-19 18:27:58 +0000 | [diff] [blame] | 17 | #define H_HAL_TAKEOVER 0x5124 |
| 18 | #define H_HAL_TAKEOVER_QUERY_MAGIC -1 |
| 19 | |
| 20 | .text |
| 21 | _GLOBAL(opal_query_takeover) |
| 22 | mfcr r0 |
| 23 | stw r0,8(r1) |
Michael Neuling | c75df6f | 2012-06-25 13:33:10 +0000 | [diff] [blame] | 24 | std r3,STK_PARAM(R3)(r1) |
| 25 | std r4,STK_PARAM(R4)(r1) |
Benjamin Herrenschmidt | 27f4488 | 2011-09-19 18:27:58 +0000 | [diff] [blame] | 26 | li r3,H_HAL_TAKEOVER |
| 27 | li r4,H_HAL_TAKEOVER_QUERY_MAGIC |
| 28 | HVSC |
Michael Neuling | c75df6f | 2012-06-25 13:33:10 +0000 | [diff] [blame] | 29 | ld r10,STK_PARAM(R3)(r1) |
Benjamin Herrenschmidt | 27f4488 | 2011-09-19 18:27:58 +0000 | [diff] [blame] | 30 | std r4,0(r10) |
Michael Neuling | c75df6f | 2012-06-25 13:33:10 +0000 | [diff] [blame] | 31 | ld r10,STK_PARAM(R4)(r1) |
Benjamin Herrenschmidt | 27f4488 | 2011-09-19 18:27:58 +0000 | [diff] [blame] | 32 | std r5,0(r10) |
| 33 | lwz r0,8(r1) |
| 34 | mtcrf 0xff,r0 |
| 35 | blr |
| 36 | |
| 37 | _GLOBAL(opal_do_takeover) |
| 38 | mfcr r0 |
| 39 | stw r0,8(r1) |
| 40 | mflr r0 |
| 41 | std r0,16(r1) |
| 42 | bl __opal_do_takeover |
| 43 | ld r0,16(r1) |
| 44 | mtlr r0 |
| 45 | lwz r0,8(r1) |
| 46 | mtcrf 0xff,r0 |
| 47 | blr |
| 48 | |
| 49 | __opal_do_takeover: |
| 50 | ld r4,0(r3) |
| 51 | ld r5,0x8(r3) |
| 52 | ld r6,0x10(r3) |
| 53 | ld r7,0x18(r3) |
| 54 | ld r8,0x20(r3) |
| 55 | ld r9,0x28(r3) |
| 56 | ld r10,0x30(r3) |
| 57 | ld r11,0x38(r3) |
| 58 | li r3,H_HAL_TAKEOVER |
| 59 | HVSC |
| 60 | blr |
| 61 | |
| 62 | .globl opal_secondary_entry |
| 63 | opal_secondary_entry: |
| 64 | mr r31,r3 |
| 65 | mfmsr r11 |
| 66 | li r12,(MSR_SF | MSR_ISF)@highest |
| 67 | sldi r12,r12,48 |
| 68 | or r11,r11,r12 |
| 69 | mtmsrd r11 |
| 70 | isync |
| 71 | mfspr r4,SPRN_PIR |
| 72 | std r4,0(r3) |
| 73 | 1: HMT_LOW |
| 74 | ld r4,8(r3) |
| 75 | cmpli cr0,r4,0 |
| 76 | beq 1b |
| 77 | HMT_MEDIUM |
| 78 | 1: addi r3,r31,16 |
| 79 | bl __opal_do_takeover |
| 80 | b 1b |
| 81 | |
| 82 | _GLOBAL(opal_enter_rtas) |
| 83 | mflr r0 |
| 84 | std r0,16(r1) |
| 85 | stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */ |
| 86 | |
| 87 | /* Because PROM is running in 32b mode, it clobbers the high order half |
| 88 | * of all registers that it saves. We therefore save those registers |
| 89 | * PROM might touch to the stack. (r0, r3-r13 are caller saved) |
| 90 | */ |
| 91 | SAVE_GPR(2, r1) |
| 92 | SAVE_GPR(13, r1) |
| 93 | SAVE_8GPRS(14, r1) |
| 94 | SAVE_10GPRS(22, r1) |
| 95 | mfcr r10 |
| 96 | mfmsr r11 |
| 97 | std r10,_CCR(r1) |
| 98 | std r11,_MSR(r1) |
| 99 | |
| 100 | /* Get the PROM entrypoint */ |
| 101 | mtlr r5 |
| 102 | |
| 103 | /* Switch MSR to 32 bits mode |
| 104 | */ |
| 105 | li r12,1 |
| 106 | rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG) |
| 107 | andc r11,r11,r12 |
| 108 | li r12,1 |
| 109 | rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG) |
| 110 | andc r11,r11,r12 |
| 111 | mtmsrd r11 |
| 112 | isync |
| 113 | |
| 114 | /* Enter RTAS here... */ |
| 115 | blrl |
| 116 | |
| 117 | /* Just make sure that r1 top 32 bits didn't get |
| 118 | * corrupt by OF |
| 119 | */ |
| 120 | rldicl r1,r1,0,32 |
| 121 | |
| 122 | /* Restore the MSR (back to 64 bits) */ |
| 123 | ld r0,_MSR(r1) |
| 124 | MTMSRD(r0) |
| 125 | isync |
| 126 | |
| 127 | /* Restore other registers */ |
| 128 | REST_GPR(2, r1) |
| 129 | REST_GPR(13, r1) |
| 130 | REST_8GPRS(14, r1) |
| 131 | REST_10GPRS(22, r1) |
| 132 | ld r4,_CCR(r1) |
| 133 | mtcr r4 |
| 134 | |
| 135 | addi r1,r1,PROM_FRAME_SIZE |
| 136 | ld r0,16(r1) |
| 137 | mtlr r0 |
| 138 | blr |