1 /* $NetBSD: hypervisor.h,v 1.14 2005/05/11 13:53:41 yamt Exp $ */ 2 3 /* 4 * 5 * Communication to/from hypervisor. 6 * 7 * Copyright (c) 2002-2004, K A Fraser 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a copy 10 * of this source file (the "Software"), to deal in the Software without 11 * restriction, including without limitation the rights to use, copy, modify, 12 * merge, publish, distribute, sublicense, and/or sell copies of the Software, 13 * and to permit persons to whom the Software is furnished to do so, subject to 14 * the following conditions: 15 * 16 * The above copyright notice and this permission notice shall be included in 17 * all copies or substantial portions of the Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 * IN THE SOFTWARE. 26 */ 27 28 29 #ifndef _XEN_HYPERVISOR_H_ 30 #define _XEN_HYPERVISOR_H_ 31 32 33 struct hypervisor_attach_args { 34 const char *haa_busname; 35 }; 36 37 struct xencons_attach_args { 38 const char *xa_device; 39 }; 40 41 struct xen_npx_attach_args { 42 const char *xa_device; 43 }; 44 45 46 #define u8 uint8_t 47 #define u16 uint16_t 48 #define u32 uint32_t 49 #define u64 uint64_t 50 #define s8 int8_t 51 #define s16 int16_t 52 #define s32 int32_t 53 #define s64 int64_t 54 55 #include <machine/xen-public/xen.h> 56 #include <machine/xen-public/dom0_ops.h> 57 #include <machine/xen-public/event_channel.h> 58 #include <machine/xen-public/physdev.h> 59 #include <machine/xen-public/io/domain_controller.h> 60 #include <machine/xen-public/io/netif.h> 61 #include <machine/xen-public/io/blkif.h> 62 63 #undef u8 64 #undef u16 65 #undef u32 66 #undef u64 67 #undef s8 68 #undef s16 69 #undef s32 70 #undef s64 71 72 73 /* 74 * a placeholder for the start of day information passed up from the hypervisor 75 */ 76 union start_info_union 77 { 78 start_info_t start_info; 79 char padding[512]; 80 }; 81 extern union start_info_union start_info_union; 82 #define xen_start_info (start_info_union.start_info) 83 84 85 /* hypervisor.c */ 86 struct intrframe; 87 void do_hypervisor_callback(struct intrframe *regs); 88 void hypervisor_notify_via_evtchn(unsigned int); 89 void hypervisor_enable_event(unsigned int); 90 91 /* hypervisor_machdep.c */ 92 void hypervisor_unmask_event(unsigned int); 93 void hypervisor_mask_event(unsigned int); 94 void hypervisor_clear_event(unsigned int); 95 void hypervisor_force_callback(void) 96 __attribute__((no_instrument_function)); /* used by mcount */ 97 void hypervisor_enable_ipl(unsigned int); 98 void hypervisor_set_ipending(u_int32_t, int, int); 99 100 /* 101 * Assembler stubs for hyper-calls. 102 */ 103 104 static inline int 105 HYPERVISOR_set_trap_table(trap_info_t *table) 106 { 107 int ret; 108 unsigned long ign1; 109 110 __asm__ __volatile__ ( 111 TRAP_INSTR 112 : "=a" (ret), "=b" (ign1) 113 : "0" (__HYPERVISOR_set_trap_table), "1" (table) 114 : "memory" ); 115 116 return ret; 117 } 118 119 static inline int 120 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count) 121 { 122 int ret; 123 unsigned long ign1, ign2, ign3; 124 125 __asm__ __volatile__ ( 126 TRAP_INSTR 127 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 128 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), 129 "3" (success_count) 130 : "memory" ); 131 132 return ret; 133 } 134 135 static inline int 136 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 137 { 138 int ret; 139 unsigned long ign1, ign2; 140 141 __asm__ __volatile__ ( 142 TRAP_INSTR 143 : "=a" (ret), "=b" (ign1), "=c" (ign2) 144 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries) 145 : "memory" ); 146 147 return ret; 148 } 149 150 static inline int 151 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) 152 { 153 int ret; 154 unsigned long ign1, ign2; 155 156 __asm__ __volatile__ ( 157 TRAP_INSTR 158 : "=a" (ret), "=b" (ign1), "=c" (ign2) 159 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp) 160 : "memory" ); 161 162 return ret; 163 } 164 165 static inline int 166 HYPERVISOR_set_callbacks( 167 unsigned long event_selector, unsigned long event_address, 168 unsigned long failsafe_selector, unsigned long failsafe_address) 169 { 170 int ret; 171 unsigned long ign1, ign2, ign3, ign4; 172 173 __asm__ __volatile__ ( 174 TRAP_INSTR 175 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 176 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector), 177 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address) 178 : "memory" ); 179 180 return ret; 181 } 182 183 static inline int 184 HYPERVISOR_fpu_taskswitch(void) 185 { 186 int ret; 187 __asm__ __volatile__ ( 188 TRAP_INSTR 189 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" ); 190 191 return ret; 192 } 193 194 static inline int 195 HYPERVISOR_yield(void) 196 { 197 int ret; 198 unsigned long ign1; 199 200 __asm__ __volatile__ ( 201 TRAP_INSTR 202 : "=a" (ret), "=b" (ign1) 203 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield) 204 : "memory" ); 205 206 return ret; 207 } 208 209 static inline int 210 HYPERVISOR_block(void) 211 { 212 int ret; 213 unsigned long ign1; 214 215 __asm__ __volatile__ ( 216 TRAP_INSTR 217 : "=a" (ret), "=b" (ign1) 218 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block) 219 : "memory" ); 220 221 return ret; 222 } 223 224 static inline int 225 HYPERVISOR_shutdown(void) 226 { 227 int ret; 228 unsigned long ign1; 229 230 __asm__ __volatile__ ( 231 TRAP_INSTR 232 : "=a" (ret), "=b" (ign1) 233 : "0" (__HYPERVISOR_sched_op), 234 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) 235 : "memory" ); 236 237 return ret; 238 } 239 240 static inline int 241 HYPERVISOR_reboot(void) 242 { 243 int ret; 244 unsigned long ign1; 245 246 __asm__ __volatile__ ( 247 TRAP_INSTR 248 : "=a" (ret), "=b" (ign1) 249 : "0" (__HYPERVISOR_sched_op), 250 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) 251 : "memory" ); 252 253 return ret; 254 } 255 256 static inline int 257 HYPERVISOR_suspend(unsigned long srec) 258 { 259 int ret; 260 unsigned long ign1, ign2; 261 262 /* NB. On suspend, control software expects a suspend record in %esi. */ 263 __asm__ __volatile__ ( 264 TRAP_INSTR 265 : "=a" (ret), "=b" (ign1), "=S" (ign2) 266 : "0" (__HYPERVISOR_sched_op), 267 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 268 "S" (srec) : "memory"); 269 270 return ret; 271 } 272 273 static inline long 274 HYPERVISOR_set_timer_op(uint64_t timeout) 275 { 276 int ret; 277 unsigned long timeout_hi = (unsigned long)(timeout>>32); 278 unsigned long timeout_lo = (unsigned long)timeout; 279 unsigned long ign1, ign2; 280 281 __asm__ __volatile__ ( 282 TRAP_INSTR 283 : "=a" (ret), "=b" (ign1), "=c" (ign2) 284 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo) 285 : "memory"); 286 287 return ret; 288 } 289 290 static inline int 291 HYPERVISOR_dom0_op(dom0_op_t *dom0_op) 292 { 293 int ret; 294 unsigned long ign1; 295 296 dom0_op->interface_version = DOM0_INTERFACE_VERSION; 297 __asm__ __volatile__ ( 298 TRAP_INSTR 299 : "=a" (ret), "=b" (ign1) 300 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op) 301 : "memory"); 302 303 return ret; 304 } 305 306 static inline int 307 HYPERVISOR_set_debugreg(int reg, unsigned long value) 308 { 309 int ret; 310 unsigned long ign1, ign2; 311 312 __asm__ __volatile__ ( 313 TRAP_INSTR 314 : "=a" (ret), "=b" (ign1), "=c" (ign2) 315 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value) 316 : "memory" ); 317 318 return ret; 319 } 320 321 static inline unsigned long 322 HYPERVISOR_get_debugreg(int reg) 323 { 324 unsigned long ret; 325 unsigned long ign1; 326 327 __asm__ __volatile__ ( 328 TRAP_INSTR 329 : "=a" (ret), "=b" (ign1) 330 : "0" (__HYPERVISOR_get_debugreg), "1" (reg) 331 : "memory" ); 332 333 return ret; 334 } 335 336 static inline int 337 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1, 338 unsigned long word2) 339 { 340 int ret; 341 unsigned long ign1, ign2, ign3; 342 343 __asm__ __volatile__ ( 344 TRAP_INSTR 345 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 346 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1), 347 "3" (word2) 348 : "memory" ); 349 350 return ret; 351 } 352 353 static inline int 354 HYPERVISOR_set_fast_trap(int idx) 355 { 356 int ret; 357 unsigned long ign1; 358 359 __asm__ __volatile__ ( 360 TRAP_INSTR 361 : "=a" (ret), "=b" (ign1) 362 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx) 363 : "memory" ); 364 365 return ret; 366 } 367 368 static inline int 369 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list, 370 unsigned long nr_extents, unsigned int extent_order) 371 { 372 int ret; 373 unsigned long ign1, ign2, ign3, ign4, ign5; 374 375 __asm__ __volatile__ ( 376 TRAP_INSTR 377 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), 378 "=D" (ign5) 379 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list), 380 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF) 381 : "memory" ); 382 383 return ret; 384 } 385 386 static inline int 387 HYPERVISOR_multicall(void *call_list, int nr_calls) 388 { 389 int ret; 390 unsigned long ign1, ign2; 391 392 __asm__ __volatile__ ( 393 TRAP_INSTR 394 : "=a" (ret), "=b" (ign1), "=c" (ign2) 395 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls) 396 : "memory" ); 397 398 return ret; 399 } 400 401 static inline int 402 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val, 403 unsigned long flags) 404 { 405 int ret; 406 unsigned long ign1, ign2, ign3; 407 408 __asm__ __volatile__ ( 409 TRAP_INSTR 410 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 411 : "0" (__HYPERVISOR_update_va_mapping), 412 "1" (page_nr), "2" (new_val), "3" (flags) 413 : "memory" ); 414 415 #ifdef notdef 416 if (__predict_false(ret < 0)) 417 panic("Failed update VA mapping: %08lx, %08lx, %08lx", 418 page_nr, new_val, flags); 419 #endif 420 421 return ret; 422 } 423 424 static inline int 425 HYPERVISOR_event_channel_op(void *op) 426 { 427 int ret; 428 unsigned long ign1; 429 430 __asm__ __volatile__ ( 431 TRAP_INSTR 432 : "=a" (ret), "=b" (ign1) 433 : "0" (__HYPERVISOR_event_channel_op), "1" (op) 434 : "memory" ); 435 436 return ret; 437 } 438 439 static inline int 440 HYPERVISOR_xen_version(int cmd) 441 { 442 int ret; 443 unsigned long ign1; 444 445 __asm__ __volatile__ ( 446 TRAP_INSTR 447 : "=a" (ret), "=b" (ign1) 448 : "0" (__HYPERVISOR_xen_version), "1" (cmd) 449 : "memory" ); 450 451 return ret; 452 } 453 454 static inline int 455 HYPERVISOR_console_io(int cmd, int count, char *str) 456 { 457 int ret; 458 unsigned long ign1, ign2, ign3; 459 460 __asm__ __volatile__ ( 461 TRAP_INSTR 462 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 463 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str) 464 : "memory" ); 465 466 return ret; 467 } 468 469 static inline int 470 HYPERVISOR_physdev_op(void *physdev_op) 471 { 472 int ret; 473 unsigned long ign1; 474 475 __asm__ __volatile__ ( 476 TRAP_INSTR 477 : "=a" (ret), "=b" (ign1) 478 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) 479 : "memory" ); 480 481 return ret; 482 } 483 484 static inline int 485 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) 486 { 487 int ret; 488 unsigned long ign1, ign2, ign3; 489 490 __asm__ __volatile__ ( 491 TRAP_INSTR 492 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 493 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop) 494 : "memory" ); 495 496 return ret; 497 } 498 499 static inline int 500 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr, 501 unsigned long new_val, unsigned long flags, domid_t domid) 502 { 503 int ret; 504 unsigned long ign1, ign2, ign3, ign4; 505 506 __asm__ __volatile__ ( 507 TRAP_INSTR 508 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 509 : "0" (__HYPERVISOR_update_va_mapping_otherdomain), 510 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) : 511 "memory" ); 512 513 return ret; 514 } 515 516 static inline int 517 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) 518 { 519 int ret; 520 unsigned long ign1, ign2; 521 522 __asm__ __volatile__ ( 523 TRAP_INSTR 524 : "=a" (ret), "=b" (ign1), "=c" (ign2) 525 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type) 526 : "memory" ); 527 528 return ret; 529 } 530 531 #endif /* _XEN_HYPERVISOR_H_ */ 532