[34] | 1 | /* |
---|
| 2 | * Copyright (C) 2005 Jimi Xenidis <jimix@watson.ibm.com>, IBM Corporation |
---|
| 3 | * |
---|
| 4 | * This program is free software; you can redistribute it and/or modify |
---|
| 5 | * it under the terms of the GNU General Public License as published by |
---|
| 6 | * the Free Software Foundation; either version 2 of the License, or |
---|
| 7 | * (at your option) any later version. |
---|
| 8 | * |
---|
| 9 | * This program is distributed in the hope that it will be useful, |
---|
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 12 | * GNU General Public License for more details. |
---|
| 13 | * |
---|
| 14 | * You should have received a copy of the GNU General Public License |
---|
| 15 | * along with this program; if not, write to the Free Software |
---|
| 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
---|
| 17 | */ |
---|
| 18 | |
---|
| 19 | #include <asm/config.h> |
---|
| 20 | #include <asm/asm-offsets.h> |
---|
| 21 | #include <asm/reg_defs.h> |
---|
| 22 | #include <asm/msr.h> |
---|
| 23 | #include <asm/processor.h> |
---|
| 24 | |
---|
| 25 | #ifdef HAS_FLOAT |
---|
| 26 | save_fp: |
---|
| 27 | addi r4, r3, VCPU_fprs - FPR_WIDTH |
---|
| 28 | stfdu fr0,FPR_WIDTH(r4) |
---|
| 29 | stfdu fr1,FPR_WIDTH(r4) |
---|
| 30 | stfdu fr2,FPR_WIDTH(r4) |
---|
| 31 | stfdu fr3,FPR_WIDTH(r4) |
---|
| 32 | stfdu fr4,FPR_WIDTH(r4) |
---|
| 33 | stfdu fr5,FPR_WIDTH(r4) |
---|
| 34 | stfdu fr6,FPR_WIDTH(r4) |
---|
| 35 | stfdu fr7,FPR_WIDTH(r4) |
---|
| 36 | stfdu fr8,FPR_WIDTH(r4) |
---|
| 37 | stfdu fr9,FPR_WIDTH(r4) |
---|
| 38 | stfdu fr10,FPR_WIDTH(r4) |
---|
| 39 | stfdu fr11,FPR_WIDTH(r4) |
---|
| 40 | stfdu fr12,FPR_WIDTH(r4) |
---|
| 41 | stfdu fr13,FPR_WIDTH(r4) |
---|
| 42 | stfdu fr14,FPR_WIDTH(r4) |
---|
| 43 | stfdu fr15,FPR_WIDTH(r4) |
---|
| 44 | stfdu fr16,FPR_WIDTH(r4) |
---|
| 45 | stfdu fr17,FPR_WIDTH(r4) |
---|
| 46 | stfdu fr18,FPR_WIDTH(r4) |
---|
| 47 | stfdu fr19,FPR_WIDTH(r4) |
---|
| 48 | stfdu fr20,FPR_WIDTH(r4) |
---|
| 49 | stfdu fr21,FPR_WIDTH(r4) |
---|
| 50 | stfdu fr22,FPR_WIDTH(r4) |
---|
| 51 | stfdu fr23,FPR_WIDTH(r4) |
---|
| 52 | stfdu fr24,FPR_WIDTH(r4) |
---|
| 53 | stfdu fr25,FPR_WIDTH(r4) |
---|
| 54 | stfdu fr26,FPR_WIDTH(r4) |
---|
| 55 | stfdu fr27,FPR_WIDTH(r4) |
---|
| 56 | stfdu fr28,FPR_WIDTH(r4) |
---|
| 57 | stfdu fr29,FPR_WIDTH(r4) |
---|
| 58 | stfdu fr30,FPR_WIDTH(r4) |
---|
| 59 | stfdu fr31,FPR_WIDTH(r4) |
---|
| 60 | mffs fr0 |
---|
| 61 | stfd fr0,VCPU_fpscr(r3) |
---|
| 62 | blr |
---|
| 63 | |
---|
| 64 | load_fp: |
---|
| 65 | lfd fr0,VCPU_fpscr(r3) |
---|
| 66 | mtfsf 0xff,fr0 |
---|
| 67 | |
---|
| 68 | addi r4, r3, VCPU_fprs - FPR_WIDTH |
---|
| 69 | lfdu fr0,FPR_WIDTH(r4) |
---|
| 70 | lfdu fr1,FPR_WIDTH(r4) |
---|
| 71 | lfdu fr2,FPR_WIDTH(r4) |
---|
| 72 | lfdu fr3,FPR_WIDTH(r4) |
---|
| 73 | lfdu fr4,FPR_WIDTH(r4) |
---|
| 74 | lfdu fr5,FPR_WIDTH(r4) |
---|
| 75 | lfdu fr6,FPR_WIDTH(r4) |
---|
| 76 | lfdu fr7,FPR_WIDTH(r4) |
---|
| 77 | lfdu fr8,FPR_WIDTH(r4) |
---|
| 78 | lfdu fr9,FPR_WIDTH(r4) |
---|
| 79 | lfdu fr10,FPR_WIDTH(r4) |
---|
| 80 | lfdu fr11,FPR_WIDTH(r4) |
---|
| 81 | lfdu fr12,FPR_WIDTH(r4) |
---|
| 82 | lfdu fr13,FPR_WIDTH(r4) |
---|
| 83 | lfdu fr14,FPR_WIDTH(r4) |
---|
| 84 | lfdu fr15,FPR_WIDTH(r4) |
---|
| 85 | lfdu fr16,FPR_WIDTH(r4) |
---|
| 86 | lfdu fr17,FPR_WIDTH(r4) |
---|
| 87 | lfdu fr18,FPR_WIDTH(r4) |
---|
| 88 | lfdu fr19,FPR_WIDTH(r4) |
---|
| 89 | lfdu fr20,FPR_WIDTH(r4) |
---|
| 90 | lfdu fr21,FPR_WIDTH(r4) |
---|
| 91 | lfdu fr22,FPR_WIDTH(r4) |
---|
| 92 | lfdu fr23,FPR_WIDTH(r4) |
---|
| 93 | lfdu fr24,FPR_WIDTH(r4) |
---|
| 94 | lfdu fr25,FPR_WIDTH(r4) |
---|
| 95 | lfdu fr26,FPR_WIDTH(r4) |
---|
| 96 | lfdu fr27,FPR_WIDTH(r4) |
---|
| 97 | lfdu fr28,FPR_WIDTH(r4) |
---|
| 98 | lfdu fr29,FPR_WIDTH(r4) |
---|
| 99 | lfdu fr30,FPR_WIDTH(r4) |
---|
| 100 | lfdu fr31,FPR_WIDTH(r4) |
---|
| 101 | blr |
---|
| 102 | #endif /* HAS_FLOAT */ |
---|
| 103 | |
---|
| 104 | #ifdef HAS_VMX |
---|
| 105 | |
---|
| 106 | #define VCPU_vr(n) (VCPU_vrs + ((n) * 16)) |
---|
| 107 | |
---|
| 108 | /* |
---|
| 109 | * We cannot rely on the domain to correctly use VRSAVE |
---|
| 110 | * so it is required that all VMX registers are saved and restored. |
---|
| 111 | */ |
---|
| 112 | save_vmx: |
---|
| 113 | mfspr r0,SPRN_VRSAVE |
---|
| 114 | stw r0,VCPU_vrsave(r3) |
---|
| 115 | |
---|
| 116 | addi r0,r3,VCPU_vr(0); stvxl vr0,0,r0 |
---|
| 117 | addi r0,r3,VCPU_vr(1); stvxl vr1,0,r0 |
---|
| 118 | addi r0,r3,VCPU_vr(2); stvxl vr2,0,r0 |
---|
| 119 | addi r0,r3,VCPU_vr(3); stvxl vr3,0,r0 |
---|
| 120 | addi r0,r3,VCPU_vr(4); stvxl vr4,0,r0 |
---|
| 121 | addi r0,r3,VCPU_vr(5); stvxl vr5,0,r0 |
---|
| 122 | addi r0,r3,VCPU_vr(6); stvxl vr6,0,r0 |
---|
| 123 | addi r0,r3,VCPU_vr(7); stvxl vr7,0,r0 |
---|
| 124 | addi r0,r3,VCPU_vr(8); stvxl vr8,0,r0 |
---|
| 125 | |
---|
| 126 | /* |
---|
| 127 | * By now vr0 should be pushed out so now is a good time to |
---|
| 128 | * get the VRSCR which can take a long time and has no dependcies |
---|
| 129 | * on the following operations. |
---|
| 130 | */ |
---|
| 131 | mfvscr vr0 |
---|
| 132 | addi r0,r3,VCPU_vscr ; stvxl vr0,0,r0 |
---|
| 133 | |
---|
| 134 | addi r0,r3,VCPU_vr(9); stvxl vr9,0,r0 |
---|
| 135 | addi r0,r3,VCPU_vr(10); stvxl vr10,0,r0 |
---|
| 136 | addi r0,r3,VCPU_vr(11); stvxl vr11,0,r0 |
---|
| 137 | addi r0,r3,VCPU_vr(12); stvxl vr12,0,r0 |
---|
| 138 | addi r0,r3,VCPU_vr(13); stvxl vr13,0,r0 |
---|
| 139 | addi r0,r3,VCPU_vr(14); stvxl vr14,0,r0 |
---|
| 140 | addi r0,r3,VCPU_vr(15); stvxl vr15,0,r0 |
---|
| 141 | addi r0,r3,VCPU_vr(16); stvxl vr16,0,r0 |
---|
| 142 | addi r0,r3,VCPU_vr(17); stvxl vr17,0,r0 |
---|
| 143 | addi r0,r3,VCPU_vr(18); stvxl vr18,0,r0 |
---|
| 144 | addi r0,r3,VCPU_vr(19); stvxl vr19,0,r0 |
---|
| 145 | addi r0,r3,VCPU_vr(20); stvxl vr20,0,r0 |
---|
| 146 | addi r0,r3,VCPU_vr(21); stvxl vr21,0,r0 |
---|
| 147 | addi r0,r3,VCPU_vr(22); stvxl vr22,0,r0 |
---|
| 148 | addi r0,r3,VCPU_vr(23); stvxl vr23,0,r0 |
---|
| 149 | addi r0,r3,VCPU_vr(24); stvxl vr24,0,r0 |
---|
| 150 | addi r0,r3,VCPU_vr(25); stvxl vr25,0,r0 |
---|
| 151 | addi r0,r3,VCPU_vr(26); stvxl vr26,0,r0 |
---|
| 152 | addi r0,r3,VCPU_vr(27); stvxl vr27,0,r0 |
---|
| 153 | addi r0,r3,VCPU_vr(28); stvxl vr28,0,r0 |
---|
| 154 | addi r0,r3,VCPU_vr(29); stvxl vr29,0,r0 |
---|
| 155 | addi r0,r3,VCPU_vr(30); stvxl vr30,0,r0 |
---|
| 156 | addi r0,r3,VCPU_vr(31); stvxl vr31,0,r0 |
---|
| 157 | blr |
---|
| 158 | |
---|
| 159 | load_vmx: |
---|
| 160 | lwz r0,VCPU_vrsave(r3) |
---|
| 161 | mtspr SPRN_VRSAVE,r0 |
---|
| 162 | |
---|
| 163 | /* |
---|
| 164 | * This operation can take a long time so we use vr31 to |
---|
| 165 | * eliminate the depency on r0 for the next load |
---|
| 166 | */ |
---|
| 167 | addi r0,r3,VCPU_vscr ; lvxl vr31,0,r0 |
---|
| 168 | mtvscr vr31 |
---|
| 169 | |
---|
| 170 | addi r0,r3,VCPU_vr(0); lvxl vr0,0,r0 |
---|
| 171 | addi r0,r3,VCPU_vr(1); lvxl vr1,0,r0 |
---|
| 172 | addi r0,r3,VCPU_vr(2); lvxl vr2,0,r0 |
---|
| 173 | addi r0,r3,VCPU_vr(3); lvxl vr3,0,r0 |
---|
| 174 | addi r0,r3,VCPU_vr(4); lvxl vr4,0,r0 |
---|
| 175 | addi r0,r3,VCPU_vr(5); lvxl vr5,0,r0 |
---|
| 176 | addi r0,r3,VCPU_vr(6); lvxl vr6,0,r0 |
---|
| 177 | addi r0,r3,VCPU_vr(7); lvxl vr7,0,r0 |
---|
| 178 | addi r0,r3,VCPU_vr(8); lvxl vr8,0,r0 |
---|
| 179 | addi r0,r3,VCPU_vr(9); lvxl vr9,0,r0 |
---|
| 180 | addi r0,r3,VCPU_vr(10); lvxl vr10,0,r0 |
---|
| 181 | addi r0,r3,VCPU_vr(11); lvxl vr11,0,r0 |
---|
| 182 | addi r0,r3,VCPU_vr(12); lvxl vr12,0,r0 |
---|
| 183 | addi r0,r3,VCPU_vr(13); lvxl vr13,0,r0 |
---|
| 184 | addi r0,r3,VCPU_vr(14); lvxl vr14,0,r0 |
---|
| 185 | addi r0,r3,VCPU_vr(15); lvxl vr15,0,r0 |
---|
| 186 | addi r0,r3,VCPU_vr(16); lvxl vr16,0,r0 |
---|
| 187 | addi r0,r3,VCPU_vr(17); lvxl vr17,0,r0 |
---|
| 188 | addi r0,r3,VCPU_vr(18); lvxl vr18,0,r0 |
---|
| 189 | addi r0,r3,VCPU_vr(19); lvxl vr19,0,r0 |
---|
| 190 | addi r0,r3,VCPU_vr(20); lvxl vr20,0,r0 |
---|
| 191 | addi r0,r3,VCPU_vr(21); lvxl vr21,0,r0 |
---|
| 192 | addi r0,r3,VCPU_vr(22); lvxl vr22,0,r0 |
---|
| 193 | addi r0,r3,VCPU_vr(23); lvxl vr23,0,r0 |
---|
| 194 | addi r0,r3,VCPU_vr(24); lvxl vr24,0,r0 |
---|
| 195 | addi r0,r3,VCPU_vr(25); lvxl vr25,0,r0 |
---|
| 196 | addi r0,r3,VCPU_vr(26); lvxl vr26,0,r0 |
---|
| 197 | addi r0,r3,VCPU_vr(27); lvxl vr27,0,r0 |
---|
| 198 | addi r0,r3,VCPU_vr(28); lvxl vr28,0,r0 |
---|
| 199 | addi r0,r3,VCPU_vr(29); lvxl vr29,0,r0 |
---|
| 200 | addi r0,r3,VCPU_vr(30); lvxl vr30,0,r0 |
---|
| 201 | addi r0,r3,VCPU_vr(31); lvxl vr31,0,r0 |
---|
| 202 | blr |
---|
| 203 | #endif /* HAS_VMX */ |
---|
| 204 | |
---|
| 205 | /* void save_float(struct exec_domain *ed) */ |
---|
| 206 | _GLOBAL(save_float) |
---|
| 207 | mflr r8 |
---|
| 208 | #ifdef HAS_FLOAT |
---|
| 209 | mfmsr r9 # save msr |
---|
| 210 | ori r0,r9,MSR_FP # turn on FPU |
---|
| 211 | mtmsr r0 |
---|
| 212 | bl save_fp # uses r3, r4 |
---|
| 213 | mtmsr r9 # restore msr |
---|
| 214 | #endif /* HAS_FLOAT */ |
---|
| 215 | #ifdef HAS_VMX |
---|
| 216 | mfmsr r9 # save msr |
---|
| 217 | oris r0,r9,MSR_VMX@h # turn on VMX |
---|
| 218 | mtmsr r0 |
---|
| 219 | bl save_vmx # uses r3 |
---|
| 220 | mtmsr r9 # restore msr |
---|
| 221 | #endif /* HAS_VMX */ |
---|
| 222 | mtlr r8 |
---|
| 223 | blr |
---|
| 224 | |
---|
| 225 | /* void load_float(struct exec_domain *ed) */ |
---|
| 226 | _GLOBAL(load_float) |
---|
| 227 | mflr r8 |
---|
| 228 | #ifdef HAS_FLOAT |
---|
| 229 | mfmsr r9 # save msr |
---|
| 230 | ori r0,r9,MSR_FP # turn on FPU |
---|
| 231 | mtmsr r0 |
---|
| 232 | bl load_fp # uses r3, r4 |
---|
| 233 | mtmsr r9 # restore msr |
---|
| 234 | #endif /* HAS_FLOAT */ |
---|
| 235 | #ifdef HAS_VMX |
---|
| 236 | mfmsr r9 # save msr |
---|
| 237 | oris r0,r9,MSR_VMX@h # turn on VMX |
---|
| 238 | mtmsr r0 |
---|
| 239 | bl load_vmx # uses r3 |
---|
| 240 | mtmsr r9 # restore msr |
---|
| 241 | #endif /* HAS_VMX */ |
---|
| 242 | mtlr r8 |
---|
| 243 | blr |
---|