1 /* $NetBSD: hypervisor.h,v 1.10 2005/03/09 22:39:20 bouyer 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_irq(unsigned int); 90 void hypervisor_disable_irq(unsigned int); 91 void hypervisor_acknowledge_irq(unsigned int); 92 93 /* hypervisor_machdep.c */ 94 void hypervisor_unmask_event(unsigned int); 95 void hypervisor_mask_event(unsigned int); 96 void hypervisor_clear_event(unsigned int); 97 void hypervisor_force_callback(void); 98 99 /* 100 * Assembler stubs for hyper-calls. 101 */ 102 103 static inline int 104 HYPERVISOR_set_trap_table(trap_info_t *table) 105 { 106 int ret; 107 unsigned long ign1; 108 109 __asm__ __volatile__ ( 110 TRAP_INSTR 111 : "=a" (ret), "=b" (ign1) 112 : "0" (__HYPERVISOR_set_trap_table), "1" (table) 113 : "memory" ); 114 115 return ret; 116 } 117 118 static inline int 119 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count) 120 { 121 int ret; 122 unsigned long ign1, ign2, ign3; 123 124 __asm__ __volatile__ ( 125 TRAP_INSTR 126 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 127 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count), 128 "3" (success_count) 129 : "memory" ); 130 131 return ret; 132 } 133 134 static inline int 135 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries) 136 { 137 int ret; 138 unsigned long ign1, ign2; 139 140 __asm__ __volatile__ ( 141 TRAP_INSTR 142 : "=a" (ret), "=b" (ign1), "=c" (ign2) 143 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries) 144 : "memory" ); 145 146 return ret; 147 } 148 149 static inline int 150 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp) 151 { 152 int ret; 153 unsigned long ign1, ign2; 154 155 __asm__ __volatile__ ( 156 TRAP_INSTR 157 : "=a" (ret), "=b" (ign1), "=c" (ign2) 158 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp) 159 : "memory" ); 160 161 return ret; 162 } 163 164 static inline int 165 HYPERVISOR_set_callbacks( 166 unsigned long event_selector, unsigned long event_address, 167 unsigned long failsafe_selector, unsigned long failsafe_address) 168 { 169 int ret; 170 unsigned long ign1, ign2, ign3, ign4; 171 172 __asm__ __volatile__ ( 173 TRAP_INSTR 174 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 175 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector), 176 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address) 177 : "memory" ); 178 179 return ret; 180 } 181 182 static inline int 183 HYPERVISOR_fpu_taskswitch(void) 184 { 185 int ret; 186 __asm__ __volatile__ ( 187 TRAP_INSTR 188 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" ); 189 190 return ret; 191 } 192 193 static inline int 194 HYPERVISOR_yield(void) 195 { 196 int ret; 197 unsigned long ign1; 198 199 __asm__ __volatile__ ( 200 TRAP_INSTR 201 : "=a" (ret), "=b" (ign1) 202 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield) 203 : "memory" ); 204 205 return ret; 206 } 207 208 static inline int 209 HYPERVISOR_block(void) 210 { 211 int ret; 212 unsigned long ign1; 213 214 __asm__ __volatile__ ( 215 TRAP_INSTR 216 : "=a" (ret), "=b" (ign1) 217 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block) 218 : "memory" ); 219 220 return ret; 221 } 222 223 static inline int 224 HYPERVISOR_shutdown(void) 225 { 226 int ret; 227 unsigned long ign1; 228 229 __asm__ __volatile__ ( 230 TRAP_INSTR 231 : "=a" (ret), "=b" (ign1) 232 : "0" (__HYPERVISOR_sched_op), 233 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift)) 234 : "memory" ); 235 236 return ret; 237 } 238 239 static inline int 240 HYPERVISOR_reboot(void) 241 { 242 int ret; 243 unsigned long ign1; 244 245 __asm__ __volatile__ ( 246 TRAP_INSTR 247 : "=a" (ret), "=b" (ign1) 248 : "0" (__HYPERVISOR_sched_op), 249 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift)) 250 : "memory" ); 251 252 return ret; 253 } 254 255 static inline int 256 HYPERVISOR_suspend(unsigned long srec) 257 { 258 int ret; 259 unsigned long ign1, ign2; 260 261 /* NB. On suspend, control software expects a suspend record in %esi. */ 262 __asm__ __volatile__ ( 263 TRAP_INSTR 264 : "=a" (ret), "=b" (ign1), "=S" (ign2) 265 : "0" (__HYPERVISOR_sched_op), 266 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)), 267 "S" (srec) : "memory"); 268 269 return ret; 270 } 271 272 static inline long 273 HYPERVISOR_set_timer_op(uint64_t timeout) 274 { 275 int ret; 276 unsigned long timeout_hi = (unsigned long)(timeout>>32); 277 unsigned long timeout_lo = (unsigned long)timeout; 278 unsigned long ign1, ign2; 279 280 __asm__ __volatile__ ( 281 TRAP_INSTR 282 : "=a" (ret), "=b" (ign1), "=c" (ign2) 283 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo) 284 : "memory"); 285 286 return ret; 287 } 288 289 static inline int 290 HYPERVISOR_dom0_op(dom0_op_t *dom0_op) 291 { 292 int ret; 293 unsigned long ign1; 294 295 dom0_op->interface_version = DOM0_INTERFACE_VERSION; 296 __asm__ __volatile__ ( 297 TRAP_INSTR 298 : "=a" (ret), "=b" (ign1) 299 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op) 300 : "memory"); 301 302 return ret; 303 } 304 305 static inline int 306 HYPERVISOR_set_debugreg(int reg, unsigned long value) 307 { 308 int ret; 309 unsigned long ign1, ign2; 310 311 __asm__ __volatile__ ( 312 TRAP_INSTR 313 : "=a" (ret), "=b" (ign1), "=c" (ign2) 314 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value) 315 : "memory" ); 316 317 return ret; 318 } 319 320 static inline unsigned long 321 HYPERVISOR_get_debugreg(int reg) 322 { 323 unsigned long ret; 324 unsigned long ign1; 325 326 __asm__ __volatile__ ( 327 TRAP_INSTR 328 : "=a" (ret), "=b" (ign1) 329 : "0" (__HYPERVISOR_get_debugreg), "1" (reg) 330 : "memory" ); 331 332 return ret; 333 } 334 335 static inline int 336 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1, 337 unsigned long word2) 338 { 339 int ret; 340 unsigned long ign1, ign2, ign3; 341 342 __asm__ __volatile__ ( 343 TRAP_INSTR 344 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 345 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1), 346 "3" (word2) 347 : "memory" ); 348 349 return ret; 350 } 351 352 static inline int 353 HYPERVISOR_set_fast_trap(int idx) 354 { 355 int ret; 356 unsigned long ign1; 357 358 __asm__ __volatile__ ( 359 TRAP_INSTR 360 : "=a" (ret), "=b" (ign1) 361 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx) 362 : "memory" ); 363 364 return ret; 365 } 366 367 static inline int 368 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list, 369 unsigned long nr_extents, unsigned int extent_order) 370 { 371 int ret; 372 unsigned long ign1, ign2, ign3, ign4, ign5; 373 374 __asm__ __volatile__ ( 375 TRAP_INSTR 376 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4), 377 "=D" (ign5) 378 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list), 379 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF) 380 : "memory" ); 381 382 return ret; 383 } 384 385 static inline int 386 HYPERVISOR_multicall(void *call_list, int nr_calls) 387 { 388 int ret; 389 unsigned long ign1, ign2; 390 391 __asm__ __volatile__ ( 392 TRAP_INSTR 393 : "=a" (ret), "=b" (ign1), "=c" (ign2) 394 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls) 395 : "memory" ); 396 397 return ret; 398 } 399 400 static inline int 401 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val, 402 unsigned long flags) 403 { 404 int ret; 405 unsigned long ign1, ign2, ign3; 406 407 __asm__ __volatile__ ( 408 TRAP_INSTR 409 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 410 : "0" (__HYPERVISOR_update_va_mapping), 411 "1" (page_nr), "2" (new_val), "3" (flags) 412 : "memory" ); 413 414 #ifdef notdef 415 if (__predict_false(ret < 0)) 416 panic("Failed update VA mapping: %08lx, %08lx, %08lx", 417 page_nr, new_val, flags); 418 #endif 419 420 return ret; 421 } 422 423 static inline int 424 HYPERVISOR_event_channel_op(void *op) 425 { 426 int ret; 427 unsigned long ign1; 428 429 __asm__ __volatile__ ( 430 TRAP_INSTR 431 : "=a" (ret), "=b" (ign1) 432 : "0" (__HYPERVISOR_event_channel_op), "1" (op) 433 : "memory" ); 434 435 return ret; 436 } 437 438 static inline int 439 HYPERVISOR_xen_version(int cmd) 440 { 441 int ret; 442 unsigned long ign1; 443 444 __asm__ __volatile__ ( 445 TRAP_INSTR 446 : "=a" (ret), "=b" (ign1) 447 : "0" (__HYPERVISOR_xen_version), "1" (cmd) 448 : "memory" ); 449 450 return ret; 451 } 452 453 static inline int 454 HYPERVISOR_console_io(int cmd, int count, char *str) 455 { 456 int ret; 457 unsigned long ign1, ign2, ign3; 458 459 __asm__ __volatile__ ( 460 TRAP_INSTR 461 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 462 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str) 463 : "memory" ); 464 465 return ret; 466 } 467 468 static inline int 469 HYPERVISOR_physdev_op(void *physdev_op) 470 { 471 int ret; 472 unsigned long ign1; 473 474 __asm__ __volatile__ ( 475 TRAP_INSTR 476 : "=a" (ret), "=b" (ign1) 477 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op) 478 : "memory" ); 479 480 return ret; 481 } 482 483 static inline int 484 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count) 485 { 486 int ret; 487 unsigned long ign1, ign2, ign3; 488 489 __asm__ __volatile__ ( 490 TRAP_INSTR 491 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3) 492 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop) 493 : "memory" ); 494 495 return ret; 496 } 497 498 static inline int 499 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr, 500 unsigned long new_val, unsigned long flags, domid_t domid) 501 { 502 int ret; 503 unsigned long ign1, ign2, ign3, ign4; 504 505 __asm__ __volatile__ ( 506 TRAP_INSTR 507 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4) 508 : "0" (__HYPERVISOR_update_va_mapping_otherdomain), 509 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) : 510 "memory" ); 511 512 return ret; 513 } 514 515 static inline int 516 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type) 517 { 518 int ret; 519 unsigned long ign1, ign2; 520 521 __asm__ __volatile__ ( 522 TRAP_INSTR 523 : "=a" (ret), "=b" (ign1), "=c" (ign2) 524 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type) 525 : "memory" ); 526 527 return ret; 528 } 529 530 #endif /* _XEN_HYPERVISOR_H_ */ 531