1 /****************************************************************************** 2 * arch/ia64/include/asm/xen/inst.h 3 * 4 * Copyright (c) 2008 Isaku Yamahata <yamahata at valinux co jp> 5 * VA Linux Systems Japan K.K. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 */ 22 23 #include <asm/xen/privop.h> 24 25 #define ia64_ivt xen_ivt 26 #define DO_SAVE_MIN XEN_DO_SAVE_MIN 27 28 #define __paravirt_switch_to xen_switch_to 29 #define __paravirt_leave_syscall xen_leave_syscall 30 #define __paravirt_work_processed_syscall xen_work_processed_syscall 31 #define __paravirt_leave_kernel xen_leave_kernel 32 #define __paravirt_pending_syscall_end xen_work_pending_syscall_end 33 #define __paravirt_work_processed_syscall_target \ 34 xen_work_processed_syscall 35 36 #define paravirt_fsyscall_table xen_fsyscall_table 37 #define paravirt_fsys_bubble_down xen_fsys_bubble_down 38 39 #define MOV_FROM_IFA(reg) \ 40 movl reg = XSI_IFA; \ 41 ;; \ 42 ld8 reg = [reg] 43 44 #define MOV_FROM_ITIR(reg) \ 45 movl reg = XSI_ITIR; \ 46 ;; \ 47 ld8 reg = [reg] 48 49 #define MOV_FROM_ISR(reg) \ 50 movl reg = XSI_ISR; \ 51 ;; \ 52 ld8 reg = [reg] 53 54 #define MOV_FROM_IHA(reg) \ 55 movl reg = XSI_IHA; \ 56 ;; \ 57 ld8 reg = [reg] 58 59 #define MOV_FROM_IPSR(pred, reg) \ 60 (pred) movl reg = XSI_IPSR; \ 61 ;; \ 62 (pred) ld8 reg = [reg] 63 64 #define MOV_FROM_IIM(reg) \ 65 movl reg = XSI_IIM; \ 66 ;; \ 67 ld8 reg = [reg] 68 69 #define MOV_FROM_IIP(reg) \ 70 movl reg = XSI_IIP; \ 71 ;; \ 72 ld8 reg = [reg] 73 74 .macro __MOV_FROM_IVR reg, clob 75 .ifc "\reg", "r8" 76 XEN_HYPER_GET_IVR 77 .exitm 78 .endif 79 .ifc "\clob", "r8" 80 XEN_HYPER_GET_IVR 81 ;; 82 mov \reg = r8 83 .exitm 84 .endif 85 86 mov \clob = r8 87 ;; 88 XEN_HYPER_GET_IVR 89 ;; 90 mov \reg = r8 91 ;; 92 mov r8 = \clob 93 .endm 94 #define MOV_FROM_IVR(reg, clob) __MOV_FROM_IVR reg, clob 95 96 .macro __MOV_FROM_PSR pred, reg, clob 97 .ifc "\reg", "r8" 98 (\pred) XEN_HYPER_GET_PSR; 99 .exitm 100 .endif 101 .ifc "\clob", "r8" 102 (\pred) XEN_HYPER_GET_PSR 103 ;; 104 (\pred) mov \reg = r8 105 .exitm 106 .endif 107 108 (\pred) mov \clob = r8 109 (\pred) XEN_HYPER_GET_PSR 110 ;; 111 (\pred) mov \reg = r8 112 (\pred) mov r8 = \clob 113 .endm 114 #define MOV_FROM_PSR(pred, reg, clob) __MOV_FROM_PSR pred, reg, clob 115 116 /* assuming ar.itc is read with interrupt disabled. */ 117 #define MOV_FROM_ITC(pred, pred_clob, reg, clob) \ 118 (pred) movl clob = XSI_ITC_OFFSET; \ 119 ;; \ 120 (pred) ld8 clob = [clob]; \ 121 (pred) mov reg = ar.itc; \ 122 ;; \ 123 (pred) add reg = reg, clob; \ 124 ;; \ 125 (pred) movl clob = XSI_ITC_LAST; \ 126 ;; \ 127 (pred) ld8 clob = [clob]; \ 128 ;; \ 129 (pred) cmp.geu.unc pred_clob, p0 = clob, reg; \ 130 ;; \ 131 (pred_clob) add reg = 1, clob; \ 132 ;; \ 133 (pred) movl clob = XSI_ITC_LAST; \ 134 ;; \ 135 (pred) st8 [clob] = reg 136 137 138 #define MOV_TO_IFA(reg, clob) \ 139 movl clob = XSI_IFA; \ 140 ;; \ 141 st8 [clob] = reg \ 142 143 #define MOV_TO_ITIR(pred, reg, clob) \ 144 (pred) movl clob = XSI_ITIR; \ 145 ;; \ 146 (pred) st8 [clob] = reg 147 148 #define MOV_TO_IHA(pred, reg, clob) \ 149 (pred) movl clob = XSI_IHA; \ 150 ;; \ 151 (pred) st8 [clob] = reg 152 153 #define MOV_TO_IPSR(pred, reg, clob) \ 154 (pred) movl clob = XSI_IPSR; \ 155 ;; \ 156 (pred) st8 [clob] = reg; \ 157 ;; 158 159 #define MOV_TO_IFS(pred, reg, clob) \ 160 (pred) movl clob = XSI_IFS; \ 161 ;; \ 162 (pred) st8 [clob] = reg; \ 163 ;; 164 165 #define MOV_TO_IIP(reg, clob) \ 166 movl clob = XSI_IIP; \ 167 ;; \ 168 st8 [clob] = reg 169 170 .macro ____MOV_TO_KR kr, reg, clob0, clob1 171 .ifc "\clob0", "r9" 172 .error "clob0 \clob0 must not be r9" 173 .endif 174 .ifc "\clob1", "r8" 175 .error "clob1 \clob1 must not be r8" 176 .endif 177 178 .ifnc "\reg", "r9" 179 .ifnc "\clob1", "r9" 180 mov \clob1 = r9 181 .endif 182 mov r9 = \reg 183 .endif 184 .ifnc "\clob0", "r8" 185 mov \clob0 = r8 186 .endif 187 mov r8 = \kr 188 ;; 189 XEN_HYPER_SET_KR 190 191 .ifnc "\reg", "r9" 192 .ifnc "\clob1", "r9" 193 mov r9 = \clob1 194 .endif 195 .endif 196 .ifnc "\clob0", "r8" 197 mov r8 = \clob0 198 .endif 199 .endm 200 201 .macro __MOV_TO_KR kr, reg, clob0, clob1 202 .ifc "\clob0", "r9" 203 ____MOV_TO_KR \kr, \reg, \clob1, \clob0 204 .exitm 205 .endif 206 .ifc "\clob1", "r8" 207 ____MOV_TO_KR \kr, \reg, \clob1, \clob0 208 .exitm 209 .endif 210 211 ____MOV_TO_KR \kr, \reg, \clob0, \clob1 212 .endm 213 214 #define MOV_TO_KR(kr, reg, clob0, clob1) \ 215 __MOV_TO_KR IA64_KR_ ## kr, reg, clob0, clob1 216 217 218 .macro __ITC_I pred, reg, clob 219 .ifc "\reg", "r8" 220 (\pred) XEN_HYPER_ITC_I 221 .exitm 222 .endif 223 .ifc "\clob", "r8" 224 (\pred) mov r8 = \reg 225 ;; 226 (\pred) XEN_HYPER_ITC_I 227 .exitm 228 .endif 229 230 (\pred) mov \clob = r8 231 (\pred) mov r8 = \reg 232 ;; 233 (\pred) XEN_HYPER_ITC_I 234 ;; 235 (\pred) mov r8 = \clob 236 ;; 237 .endm 238 #define ITC_I(pred, reg, clob) __ITC_I pred, reg, clob 239 240 .macro __ITC_D pred, reg, clob 241 .ifc "\reg", "r8" 242 (\pred) XEN_HYPER_ITC_D 243 ;; 244 .exitm 245 .endif 246 .ifc "\clob", "r8" 247 (\pred) mov r8 = \reg 248 ;; 249 (\pred) XEN_HYPER_ITC_D 250 ;; 251 .exitm 252 .endif 253 254 (\pred) mov \clob = r8 255 (\pred) mov r8 = \reg 256 ;; 257 (\pred) XEN_HYPER_ITC_D 258 ;; 259 (\pred) mov r8 = \clob 260 ;; 261 .endm 262 #define ITC_D(pred, reg, clob) __ITC_D pred, reg, clob 263 264 .macro __ITC_I_AND_D pred_i, pred_d, reg, clob 265 .ifc "\reg", "r8" 266 (\pred_i)XEN_HYPER_ITC_I 267 ;; 268 (\pred_d)XEN_HYPER_ITC_D 269 ;; 270 .exitm 271 .endif 272 .ifc "\clob", "r8" 273 mov r8 = \reg 274 ;; 275 (\pred_i)XEN_HYPER_ITC_I 276 ;; 277 (\pred_d)XEN_HYPER_ITC_D 278 ;; 279 .exitm 280 .endif 281 282 mov \clob = r8 283 mov r8 = \reg 284 ;; 285 (\pred_i)XEN_HYPER_ITC_I 286 ;; 287 (\pred_d)XEN_HYPER_ITC_D 288 ;; 289 mov r8 = \clob 290 ;; 291 .endm 292 #define ITC_I_AND_D(pred_i, pred_d, reg, clob) \ 293 __ITC_I_AND_D pred_i, pred_d, reg, clob 294 295 .macro __THASH pred, reg0, reg1, clob 296 .ifc "\reg0", "r8" 297 (\pred) mov r8 = \reg1 298 (\pred) XEN_HYPER_THASH 299 .exitm 300 .endc 301 .ifc "\reg1", "r8" 302 (\pred) XEN_HYPER_THASH 303 ;; 304 (\pred) mov \reg0 = r8 305 ;; 306 .exitm 307 .endif 308 .ifc "\clob", "r8" 309 (\pred) mov r8 = \reg1 310 (\pred) XEN_HYPER_THASH 311 ;; 312 (\pred) mov \reg0 = r8 313 ;; 314 .exitm 315 .endif 316 317 (\pred) mov \clob = r8 318 (\pred) mov r8 = \reg1 319 (\pred) XEN_HYPER_THASH 320 ;; 321 (\pred) mov \reg0 = r8 322 (\pred) mov r8 = \clob 323 ;; 324 .endm 325 #define THASH(pred, reg0, reg1, clob) __THASH pred, reg0, reg1, clob 326 327 #define SSM_PSR_IC_AND_DEFAULT_BITS_AND_SRLZ_I(clob0, clob1) \ 328 mov clob0 = 1; \ 329 movl clob1 = XSI_PSR_IC; \ 330 ;; \ 331 st4 [clob1] = clob0 \ 332 ;; 333 334 #define SSM_PSR_IC_AND_SRLZ_D(clob0, clob1) \ 335 ;; \ 336 srlz.d; \ 337 mov clob1 = 1; \ 338 movl clob0 = XSI_PSR_IC; \ 339 ;; \ 340 st4 [clob0] = clob1 341 342 #define RSM_PSR_IC(clob) \ 343 movl clob = XSI_PSR_IC; \ 344 ;; \ 345 st4 [clob] = r0; \ 346 ;; 347 348 /* pred will be clobbered */ 349 #define MASK_TO_PEND_OFS (-1) 350 #define SSM_PSR_I(pred, pred_clob, clob) \ 351 (pred) movl clob = XSI_PSR_I_ADDR \ 352 ;; \ 353 (pred) ld8 clob = [clob] \ 354 ;; \ 355 /* if (pred) vpsr.i = 1 */ \ 356 /* if (pred) (vcpu->vcpu_info->evtchn_upcall_mask)=0 */ \ 357 (pred) st1 [clob] = r0, MASK_TO_PEND_OFS \ 358 ;; \ 359 /* if (vcpu->vcpu_info->evtchn_upcall_pending) */ \ 360 (pred) ld1 clob = [clob] \ 361 ;; \ 362 (pred) cmp.ne.unc pred_clob, p0 = clob, r0 \ 363 ;; \ 364 (pred_clob)XEN_HYPER_SSM_I /* do areal ssm psr.i */ 365 366 #define RSM_PSR_I(pred, clob0, clob1) \ 367 movl clob0 = XSI_PSR_I_ADDR; \ 368 mov clob1 = 1; \ 369 ;; \ 370 ld8 clob0 = [clob0]; \ 371 ;; \ 372 (pred) st1 [clob0] = clob1 373 374 #define RSM_PSR_I_IC(clob0, clob1, clob2) \ 375 movl clob0 = XSI_PSR_I_ADDR; \ 376 movl clob1 = XSI_PSR_IC; \ 377 ;; \ 378 ld8 clob0 = [clob0]; \ 379 mov clob2 = 1; \ 380 ;; \ 381 /* note: clears both vpsr.i and vpsr.ic! */ \ 382 st1 [clob0] = clob2; \ 383 st4 [clob1] = r0; \ 384 ;; 385 386 #define RSM_PSR_DT \ 387 XEN_HYPER_RSM_PSR_DT 388 389 #define RSM_PSR_BE_I(clob0, clob1) \ 390 RSM_PSR_I(p0, clob0, clob1); \ 391 rum psr.be 392 393 #define SSM_PSR_DT_AND_SRLZ_I \ 394 XEN_HYPER_SSM_PSR_DT 395 396 #define BSW_0(clob0, clob1, clob2) \ 397 ;; \ 398 /* r16-r31 all now hold bank1 values */ \ 399 mov clob2 = ar.unat; \ 400 movl clob0 = XSI_BANK1_R16; \ 401 movl clob1 = XSI_BANK1_R16 + 8; \ 402 ;; \ 403 .mem.offset 0, 0; st8.spill [clob0] = r16, 16; \ 404 .mem.offset 8, 0; st8.spill [clob1] = r17, 16; \ 405 ;; \ 406 .mem.offset 0, 0; st8.spill [clob0] = r18, 16; \ 407 .mem.offset 8, 0; st8.spill [clob1] = r19, 16; \ 408 ;; \ 409 .mem.offset 0, 0; st8.spill [clob0] = r20, 16; \ 410 .mem.offset 8, 0; st8.spill [clob1] = r21, 16; \ 411 ;; \ 412 .mem.offset 0, 0; st8.spill [clob0] = r22, 16; \ 413 .mem.offset 8, 0; st8.spill [clob1] = r23, 16; \ 414 ;; \ 415 .mem.offset 0, 0; st8.spill [clob0] = r24, 16; \ 416 .mem.offset 8, 0; st8.spill [clob1] = r25, 16; \ 417 ;; \ 418 .mem.offset 0, 0; st8.spill [clob0] = r26, 16; \ 419 .mem.offset 8, 0; st8.spill [clob1] = r27, 16; \ 420 ;; \ 421 .mem.offset 0, 0; st8.spill [clob0] = r28, 16; \ 422 .mem.offset 8, 0; st8.spill [clob1] = r29, 16; \ 423 ;; \ 424 .mem.offset 0, 0; st8.spill [clob0] = r30, 16; \ 425 .mem.offset 8, 0; st8.spill [clob1] = r31, 16; \ 426 ;; \ 427 mov clob1 = ar.unat; \ 428 movl clob0 = XSI_B1NAT; \ 429 ;; \ 430 st8 [clob0] = clob1; \ 431 mov ar.unat = clob2; \ 432 movl clob0 = XSI_BANKNUM; \ 433 ;; \ 434 st4 [clob0] = r0 435 436 437 /* FIXME: THIS CODE IS NOT NaT SAFE! */ 438 #define XEN_BSW_1(clob) \ 439 mov clob = ar.unat; \ 440 movl r30 = XSI_B1NAT; \ 441 ;; \ 442 ld8 r30 = [r30]; \ 443 mov r31 = 1; \ 444 ;; \ 445 mov ar.unat = r30; \ 446 movl r30 = XSI_BANKNUM; \ 447 ;; \ 448 st4 [r30] = r31; \ 449 movl r30 = XSI_BANK1_R16; \ 450 movl r31 = XSI_BANK1_R16+8; \ 451 ;; \ 452 ld8.fill r16 = [r30], 16; \ 453 ld8.fill r17 = [r31], 16; \ 454 ;; \ 455 ld8.fill r18 = [r30], 16; \ 456 ld8.fill r19 = [r31], 16; \ 457 ;; \ 458 ld8.fill r20 = [r30], 16; \ 459 ld8.fill r21 = [r31], 16; \ 460 ;; \ 461 ld8.fill r22 = [r30], 16; \ 462 ld8.fill r23 = [r31], 16; \ 463 ;; \ 464 ld8.fill r24 = [r30], 16; \ 465 ld8.fill r25 = [r31], 16; \ 466 ;; \ 467 ld8.fill r26 = [r30], 16; \ 468 ld8.fill r27 = [r31], 16; \ 469 ;; \ 470 ld8.fill r28 = [r30], 16; \ 471 ld8.fill r29 = [r31], 16; \ 472 ;; \ 473 ld8.fill r30 = [r30]; \ 474 ld8.fill r31 = [r31]; \ 475 ;; \ 476 mov ar.unat = clob 477 478 #define BSW_1(clob0, clob1) XEN_BSW_1(clob1) 479 480 481 #define COVER \ 482 XEN_HYPER_COVER 483 484 #define RFI \ 485 XEN_HYPER_RFI; \ 486 dv_serialize_data 487