1 /****************************************************************************** 2 * displif.h 3 * 4 * Unified display device I/O interface for Xen guest OSes. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a copy 7 * of this software and associated documentation files (the "Software"), to 8 * deal in the Software without restriction, including without limitation the 9 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 * sell copies of the Software, and to permit persons to whom the Software is 11 * furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Copyright (C) 2016-2017 EPAM Systems Inc. 25 * 26 * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com> 27 * Oleksandr Grytsov <oleksandr_grytsov@epam.com> 28 */ 29 30 #ifndef __XEN_PUBLIC_IO_DISPLIF_H__ 31 #define __XEN_PUBLIC_IO_DISPLIF_H__ 32 33 #include "ring.h" 34 #include "../grant_table.h" 35 36 /* 37 ****************************************************************************** 38 * Protocol version 39 ****************************************************************************** 40 */ 41 #define XENDISPL_PROTOCOL_VERSION "1" 42 43 /* 44 ****************************************************************************** 45 * Main features provided by the protocol 46 ****************************************************************************** 47 * This protocol aims to provide a unified protocol which fits more 48 * sophisticated use-cases than a framebuffer device can handle. At the 49 * moment basic functionality is supported with the intention to be extended: 50 * o multiple dynamically allocated/destroyed framebuffers 51 * o buffers of arbitrary sizes 52 * o buffer allocation at either back or front end 53 * o better configuration options including multiple display support 54 * 55 * Note: existing fbif can be used together with displif running at the 56 * same time, e.g. on Linux one provides framebuffer and another DRM/KMS 57 * 58 * Note: display resolution (XenStore's "resolution" property) defines 59 * visible area of the virtual display. At the same time resolution of 60 * the display and frame buffers may differ: buffers can be smaller, equal 61 * or bigger than the visible area. This is to enable use-cases, where backend 62 * may do some post-processing of the display and frame buffers supplied, 63 * e.g. those buffers can be just a part of the final composition. 64 * 65 ****************************************************************************** 66 * Direction of improvements 67 ****************************************************************************** 68 * Future extensions to the existing protocol may include: 69 * o display/connector cloning 70 * o allocation of objects other than display buffers 71 * o plane/overlay support 72 * o scaling support 73 * o rotation support 74 * 75 ****************************************************************************** 76 * Feature and Parameter Negotiation 77 ****************************************************************************** 78 * 79 * Front->back notifications: when enqueuing a new request, sending a 80 * notification can be made conditional on xendispl_req (i.e., the generic 81 * hold-off mechanism provided by the ring macros). Backends must set 82 * xendispl_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()). 83 * 84 * Back->front notifications: when enqueuing a new response, sending a 85 * notification can be made conditional on xendispl_resp (i.e., the generic 86 * hold-off mechanism provided by the ring macros). Frontends must set 87 * xendispl_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()). 88 * 89 * The two halves of a para-virtual display driver utilize nodes within 90 * XenStore to communicate capabilities and to negotiate operating parameters. 91 * This section enumerates these nodes which reside in the respective front and 92 * backend portions of XenStore, following the XenBus convention. 93 * 94 * All data in XenStore is stored as strings. Nodes specifying numeric 95 * values are encoded in decimal. Integer value ranges listed below are 96 * expressed as fixed sized integer types capable of storing the conversion 97 * of a properly formated node string, without loss of information. 98 * 99 ****************************************************************************** 100 * Example configuration 101 ****************************************************************************** 102 * 103 * Note: depending on the use-case backend can expose more display connectors 104 * than the underlying HW physically has by employing SW graphics compositors 105 * 106 * This is an example of backend and frontend configuration: 107 * 108 *--------------------------------- Backend ----------------------------------- 109 * 110 * /local/domain/0/backend/vdispl/1/0/frontend-id = "1" 111 * /local/domain/0/backend/vdispl/1/0/frontend = "/local/domain/1/device/vdispl/0" 112 * /local/domain/0/backend/vdispl/1/0/state = "4" 113 * /local/domain/0/backend/vdispl/1/0/versions = "1,2" 114 * 115 *--------------------------------- Frontend ---------------------------------- 116 * 117 * /local/domain/1/device/vdispl/0/backend-id = "0" 118 * /local/domain/1/device/vdispl/0/backend = "/local/domain/0/backend/vdispl/1/0" 119 * /local/domain/1/device/vdispl/0/state = "4" 120 * /local/domain/1/device/vdispl/0/version = "1" 121 * /local/domain/1/device/vdispl/0/be-alloc = "1" 122 * 123 *-------------------------- Connector 0 configuration ------------------------ 124 * 125 * /local/domain/1/device/vdispl/0/0/resolution = "1920x1080" 126 * /local/domain/1/device/vdispl/0/0/req-ring-ref = "2832" 127 * /local/domain/1/device/vdispl/0/0/req-event-channel = "15" 128 * /local/domain/1/device/vdispl/0/0/evt-ring-ref = "387" 129 * /local/domain/1/device/vdispl/0/0/evt-event-channel = "16" 130 * 131 *-------------------------- Connector 1 configuration ------------------------ 132 * 133 * /local/domain/1/device/vdispl/0/1/resolution = "800x600" 134 * /local/domain/1/device/vdispl/0/1/req-ring-ref = "2833" 135 * /local/domain/1/device/vdispl/0/1/req-event-channel = "17" 136 * /local/domain/1/device/vdispl/0/1/evt-ring-ref = "388" 137 * /local/domain/1/device/vdispl/0/1/evt-event-channel = "18" 138 * 139 ****************************************************************************** 140 * Backend XenBus Nodes 141 ****************************************************************************** 142 * 143 *----------------------------- Protocol version ------------------------------ 144 * 145 * versions 146 * Values: <string> 147 * 148 * List of XENDISPL_LIST_SEPARATOR separated protocol versions supported 149 * by the backend. For example "1,2,3". 150 * 151 ****************************************************************************** 152 * Frontend XenBus Nodes 153 ****************************************************************************** 154 * 155 *-------------------------------- Addressing --------------------------------- 156 * 157 * dom-id 158 * Values: <uint16_t> 159 * 160 * Domain identifier. 161 * 162 * dev-id 163 * Values: <uint16_t> 164 * 165 * Device identifier. 166 * 167 * conn-idx 168 * Values: <uint8_t> 169 * 170 * Zero based contigous index of the connector. 171 * /local/domain/<dom-id>/device/vdispl/<dev-id>/<conn-idx>/... 172 * 173 *----------------------------- Protocol version ------------------------------ 174 * 175 * version 176 * Values: <string> 177 * 178 * Protocol version, chosen among the ones supported by the backend. 179 * 180 *------------------------- Backend buffer allocation ------------------------- 181 * 182 * be-alloc 183 * Values: "0", "1" 184 * 185 * If value is set to "1", then backend can be a buffer provider/allocator 186 * for this domain during XENDISPL_OP_DBUF_CREATE operation (see below 187 * for negotiation). 188 * If value is not "1" or omitted frontend must allocate buffers itself. 189 * 190 *----------------------------- Connector settings ---------------------------- 191 * 192 * resolution 193 * Values: <width, uint32_t>x<height, uint32_t> 194 * 195 * Width and height of the connector in pixels separated by 196 * XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the 197 * display. 198 * 199 *------------------ Connector Request Transport Parameters ------------------- 200 * 201 * This communication path is used to deliver requests from frontend to backend 202 * and get the corresponding responses from backend to frontend, 203 * set up per connector. 204 * 205 * req-event-channel 206 * Values: <uint32_t> 207 * 208 * The identifier of the Xen connector's control event channel 209 * used to signal activity in the ring buffer. 210 * 211 * req-ring-ref 212 * Values: <uint32_t> 213 * 214 * The Xen grant reference granting permission for the backend to map 215 * a sole page of connector's control ring buffer. 216 * 217 *------------------- Connector Event Transport Parameters -------------------- 218 * 219 * This communication path is used to deliver asynchronous events from backend 220 * to frontend, set up per connector. 221 * 222 * evt-event-channel 223 * Values: <uint32_t> 224 * 225 * The identifier of the Xen connector's event channel 226 * used to signal activity in the ring buffer. 227 * 228 * evt-ring-ref 229 * Values: <uint32_t> 230 * 231 * The Xen grant reference granting permission for the backend to map 232 * a sole page of connector's event ring buffer. 233 */ 234 235 /* 236 ****************************************************************************** 237 * STATE DIAGRAMS 238 ****************************************************************************** 239 * 240 * Tool stack creates front and back state nodes with initial state 241 * XenbusStateInitialising. 242 * Tool stack creates and sets up frontend display configuration 243 * nodes per domain. 244 * 245 *-------------------------------- Normal flow -------------------------------- 246 * 247 * Front Back 248 * ================================= ===================================== 249 * XenbusStateInitialising XenbusStateInitialising 250 * o Query backend device identification 251 * data. 252 * o Open and validate backend device. 253 * | 254 * | 255 * V 256 * XenbusStateInitWait 257 * 258 * o Query frontend configuration 259 * o Allocate and initialize 260 * event channels per configured 261 * connector. 262 * o Publish transport parameters 263 * that will be in effect during 264 * this connection. 265 * | 266 * | 267 * V 268 * XenbusStateInitialised 269 * 270 * o Query frontend transport parameters. 271 * o Connect to the event channels. 272 * | 273 * | 274 * V 275 * XenbusStateConnected 276 * 277 * o Create and initialize OS 278 * virtual display connectors 279 * as per configuration. 280 * | 281 * | 282 * V 283 * XenbusStateConnected 284 * 285 * XenbusStateUnknown 286 * XenbusStateClosed 287 * XenbusStateClosing 288 * o Remove virtual display device 289 * o Remove event channels 290 * | 291 * | 292 * V 293 * XenbusStateClosed 294 * 295 *------------------------------- Recovery flow ------------------------------- 296 * 297 * In case of frontend unrecoverable errors backend handles that as 298 * if frontend goes into the XenbusStateClosed state. 299 * 300 * In case of backend unrecoverable errors frontend tries removing 301 * the virtualized device. If this is possible at the moment of error, 302 * then frontend goes into the XenbusStateInitialising state and is ready for 303 * new connection with backend. If the virtualized device is still in use and 304 * cannot be removed, then frontend goes into the XenbusStateReconfiguring state 305 * until either the virtualized device is removed or backend initiates a new 306 * connection. On the virtualized device removal frontend goes into the 307 * XenbusStateInitialising state. 308 * 309 * Note on XenbusStateReconfiguring state of the frontend: if backend has 310 * unrecoverable errors then frontend cannot send requests to the backend 311 * and thus cannot provide functionality of the virtualized device anymore. 312 * After backend is back to normal the virtualized device may still hold some 313 * state: configuration in use, allocated buffers, client application state etc. 314 * In most cases, this will require frontend to implement complex recovery 315 * reconnect logic. Instead, by going into XenbusStateReconfiguring state, 316 * frontend will make sure no new clients of the virtualized device are 317 * accepted, allow existing client(s) to exit gracefully by signaling error 318 * state etc. 319 * Once all the clients are gone frontend can reinitialize the virtualized 320 * device and get into XenbusStateInitialising state again signaling the 321 * backend that a new connection can be made. 322 * 323 * There are multiple conditions possible under which frontend will go from 324 * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS 325 * specific. For example: 326 * 1. The underlying OS framework may provide callbacks to signal that the last 327 * client of the virtualized device has gone and the device can be removed 328 * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) 329 * to periodically check if this is the right time to re-try removal of 330 * the virtualized device. 331 * 3. By any other means. 332 * 333 ****************************************************************************** 334 * REQUEST CODES 335 ****************************************************************************** 336 * Request codes [0; 15] are reserved and must not be used 337 */ 338 339 #define XENDISPL_OP_DBUF_CREATE 0x10 340 #define XENDISPL_OP_DBUF_DESTROY 0x11 341 #define XENDISPL_OP_FB_ATTACH 0x12 342 #define XENDISPL_OP_FB_DETACH 0x13 343 #define XENDISPL_OP_SET_CONFIG 0x14 344 #define XENDISPL_OP_PG_FLIP 0x15 345 346 /* 347 ****************************************************************************** 348 * EVENT CODES 349 ****************************************************************************** 350 */ 351 #define XENDISPL_EVT_PG_FLIP 0x00 352 353 /* 354 ****************************************************************************** 355 * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS 356 ****************************************************************************** 357 */ 358 #define XENDISPL_DRIVER_NAME "vdispl" 359 360 #define XENDISPL_LIST_SEPARATOR "," 361 #define XENDISPL_RESOLUTION_SEPARATOR "x" 362 363 #define XENDISPL_FIELD_BE_VERSIONS "versions" 364 #define XENDISPL_FIELD_FE_VERSION "version" 365 #define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref" 366 #define XENDISPL_FIELD_REQ_CHANNEL "req-event-channel" 367 #define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref" 368 #define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel" 369 #define XENDISPL_FIELD_RESOLUTION "resolution" 370 #define XENDISPL_FIELD_BE_ALLOC "be-alloc" 371 372 /* 373 ****************************************************************************** 374 * STATUS RETURN CODES 375 ****************************************************************************** 376 * 377 * Status return code is zero on success and -XEN_EXX on failure. 378 * 379 ****************************************************************************** 380 * Assumptions 381 ****************************************************************************** 382 * o usage of grant reference 0 as invalid grant reference: 383 * grant reference 0 is valid, but never exposed to a PV driver, 384 * because of the fact it is already in use/reserved by the PV console. 385 * o all references in this document to page sizes must be treated 386 * as pages of size XEN_PAGE_SIZE unless otherwise noted. 387 * 388 ****************************************************************************** 389 * Description of the protocol between frontend and backend driver 390 ****************************************************************************** 391 * 392 * The two halves of a Para-virtual display driver communicate with 393 * each other using shared pages and event channels. 394 * Shared page contains a ring with request/response packets. 395 * 396 * All reserved fields in the structures below must be 0. 397 * Display buffers's cookie of value 0 is treated as invalid. 398 * Framebuffer's cookie of value 0 is treated as invalid. 399 * 400 * For all request/response/event packets that use cookies: 401 * dbuf_cookie - uint64_t, unique to guest domain value used by the backend 402 * to map remote display buffer to its local one 403 * fb_cookie - uint64_t, unique to guest domain value used by the backend 404 * to map remote framebuffer to its local one 405 * 406 *---------------------------------- Requests --------------------------------- 407 * 408 * All requests/responses, which are not connector specific, must be sent over 409 * control ring of the connector which has the index value of 0: 410 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 411 * 412 * All request packets have the same length (64 octets) 413 * All request packets have common header: 414 * 0 1 2 3 octet 415 * +----------------+----------------+----------------+----------------+ 416 * | id | operation | reserved | 4 417 * +----------------+----------------+----------------+----------------+ 418 * | reserved | 8 419 * +----------------+----------------+----------------+----------------+ 420 * id - uint16_t, private guest value, echoed in response 421 * operation - uint8_t, operation code, XENDISPL_OP_??? 422 * 423 * Request dbuf creation - request creation of a display buffer. 424 * 0 1 2 3 octet 425 * +----------------+----------------+----------------+----------------+ 426 * | id |_OP_DBUF_CREATE | reserved | 4 427 * +----------------+----------------+----------------+----------------+ 428 * | reserved | 8 429 * +----------------+----------------+----------------+----------------+ 430 * | dbuf_cookie low 32-bit | 12 431 * +----------------+----------------+----------------+----------------+ 432 * | dbuf_cookie high 32-bit | 16 433 * +----------------+----------------+----------------+----------------+ 434 * | width | 20 435 * +----------------+----------------+----------------+----------------+ 436 * | height | 24 437 * +----------------+----------------+----------------+----------------+ 438 * | bpp | 28 439 * +----------------+----------------+----------------+----------------+ 440 * | buffer_sz | 32 441 * +----------------+----------------+----------------+----------------+ 442 * | flags | 36 443 * +----------------+----------------+----------------+----------------+ 444 * | gref_directory | 40 445 * +----------------+----------------+----------------+----------------+ 446 * | reserved | 44 447 * +----------------+----------------+----------------+----------------+ 448 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 449 * +----------------+----------------+----------------+----------------+ 450 * | reserved | 64 451 * +----------------+----------------+----------------+----------------+ 452 * 453 * Must be sent over control ring of the connector which has the index 454 * value of 0: 455 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 456 * All unused bits in flags field must be set to 0. 457 * 458 * An attempt to create multiple display buffers with the same dbuf_cookie is 459 * an error. dbuf_cookie can be re-used after destroying the corresponding 460 * display buffer. 461 * 462 * Width and height of the display buffers can be smaller, equal or bigger 463 * than the connector's resolution. Depth/pixel format of the individual 464 * buffers can differ as well. 465 * 466 * width - uint32_t, width in pixels 467 * height - uint32_t, height in pixels 468 * bpp - uint32_t, bits per pixel 469 * buffer_sz - uint32_t, buffer size to be allocated, octets 470 * flags - uint32_t, flags of the operation 471 * o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested 472 * to allocate the buffer with the parameters provided in this request. 473 * Page directory is handled as follows: 474 * Frontend on request: 475 * o allocates pages for the directory (gref_directory, 476 * gref_dir_next_page(s) 477 * o grants permissions for the pages of the directory to the backend 478 * o sets gref_dir_next_page fields 479 * Backend on response: 480 * o grants permissions for the pages of the buffer allocated to 481 * the frontend 482 * o fills in page directory with grant references 483 * (gref[] in struct xendispl_page_directory) 484 * gref_directory - grant_ref_t, a reference to the first shared page 485 * describing shared buffer references. At least one page exists. If shared 486 * buffer size (buffer_sz) exceeds what can be addressed by this single page, 487 * then reference to the next page must be supplied (see gref_dir_next_page 488 * below) 489 */ 490 491 #define XENDISPL_DBUF_FLG_REQ_ALLOC (1 << 0) 492 493 struct xendispl_dbuf_create_req { 494 uint64_t dbuf_cookie; 495 uint32_t width; 496 uint32_t height; 497 uint32_t bpp; 498 uint32_t buffer_sz; 499 uint32_t flags; 500 grant_ref_t gref_directory; 501 }; 502 503 /* 504 * Shared page for XENDISPL_OP_DBUF_CREATE buffer descriptor (gref_directory in 505 * the request) employs a list of pages, describing all pages of the shared 506 * data buffer: 507 * 0 1 2 3 octet 508 * +----------------+----------------+----------------+----------------+ 509 * | gref_dir_next_page | 4 510 * +----------------+----------------+----------------+----------------+ 511 * | gref[0] | 8 512 * +----------------+----------------+----------------+----------------+ 513 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 514 * +----------------+----------------+----------------+----------------+ 515 * | gref[i] | i*4+8 516 * +----------------+----------------+----------------+----------------+ 517 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 518 * +----------------+----------------+----------------+----------------+ 519 * | gref[N - 1] | N*4+8 520 * +----------------+----------------+----------------+----------------+ 521 * 522 * gref_dir_next_page - grant_ref_t, reference to the next page describing 523 * page directory. Must be 0 if there are no more pages in the list. 524 * gref[i] - grant_ref_t, reference to a shared page of the buffer 525 * allocated at XENDISPL_OP_DBUF_CREATE 526 * 527 * Number of grant_ref_t entries in the whole page directory is not 528 * passed, but instead can be calculated as: 529 * num_grefs_total = (XENDISPL_OP_DBUF_CREATE.buffer_sz + XEN_PAGE_SIZE - 1) / 530 * XEN_PAGE_SIZE 531 */ 532 533 struct xendispl_page_directory { 534 grant_ref_t gref_dir_next_page; 535 grant_ref_t gref[1]; /* Variable length */ 536 }; 537 538 /* 539 * Request dbuf destruction - destroy a previously allocated display buffer: 540 * 0 1 2 3 octet 541 * +----------------+----------------+----------------+----------------+ 542 * | id |_OP_DBUF_DESTROY| reserved | 4 543 * +----------------+----------------+----------------+----------------+ 544 * | reserved | 8 545 * +----------------+----------------+----------------+----------------+ 546 * | dbuf_cookie low 32-bit | 12 547 * +----------------+----------------+----------------+----------------+ 548 * | dbuf_cookie high 32-bit | 16 549 * +----------------+----------------+----------------+----------------+ 550 * | reserved | 20 551 * +----------------+----------------+----------------+----------------+ 552 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 553 * +----------------+----------------+----------------+----------------+ 554 * | reserved | 64 555 * +----------------+----------------+----------------+----------------+ 556 * 557 * Must be sent over control ring of the connector which has the index 558 * value of 0: 559 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 560 */ 561 562 struct xendispl_dbuf_destroy_req { 563 uint64_t dbuf_cookie; 564 }; 565 566 /* 567 * Request framebuffer attachment - request attachment of a framebuffer to 568 * previously created display buffer. 569 * 0 1 2 3 octet 570 * +----------------+----------------+----------------+----------------+ 571 * | id | _OP_FB_ATTACH | reserved | 4 572 * +----------------+----------------+----------------+----------------+ 573 * | reserved | 8 574 * +----------------+----------------+----------------+----------------+ 575 * | dbuf_cookie low 32-bit | 12 576 * +----------------+----------------+----------------+----------------+ 577 * | dbuf_cookie high 32-bit | 16 578 * +----------------+----------------+----------------+----------------+ 579 * | fb_cookie low 32-bit | 20 580 * +----------------+----------------+----------------+----------------+ 581 * | fb_cookie high 32-bit | 24 582 * +----------------+----------------+----------------+----------------+ 583 * | width | 28 584 * +----------------+----------------+----------------+----------------+ 585 * | height | 32 586 * +----------------+----------------+----------------+----------------+ 587 * | pixel_format | 36 588 * +----------------+----------------+----------------+----------------+ 589 * | reserved | 40 590 * +----------------+----------------+----------------+----------------+ 591 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 592 * +----------------+----------------+----------------+----------------+ 593 * | reserved | 64 594 * +----------------+----------------+----------------+----------------+ 595 * 596 * Must be sent over control ring of the connector which has the index 597 * value of 0: 598 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 599 * Width and height can be smaller, equal or bigger than the connector's 600 * resolution. 601 * 602 * An attempt to create multiple frame buffers with the same fb_cookie is 603 * an error. fb_cookie can be re-used after destroying the corresponding 604 * frame buffer. 605 * 606 * width - uint32_t, width in pixels 607 * height - uint32_t, height in pixels 608 * pixel_format - uint32_t, pixel format of the framebuffer, FOURCC code 609 */ 610 611 struct xendispl_fb_attach_req { 612 uint64_t dbuf_cookie; 613 uint64_t fb_cookie; 614 uint32_t width; 615 uint32_t height; 616 uint32_t pixel_format; 617 }; 618 619 /* 620 * Request framebuffer detach - detach a previously 621 * attached framebuffer from the display buffer in request: 622 * 0 1 2 3 octet 623 * +----------------+----------------+----------------+----------------+ 624 * | id | _OP_FB_DETACH | reserved | 4 625 * +----------------+----------------+----------------+----------------+ 626 * | reserved | 8 627 * +----------------+----------------+----------------+----------------+ 628 * | fb_cookie low 32-bit | 12 629 * +----------------+----------------+----------------+----------------+ 630 * | fb_cookie high 32-bit | 16 631 * +----------------+----------------+----------------+----------------+ 632 * | reserved | 20 633 * +----------------+----------------+----------------+----------------+ 634 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 635 * +----------------+----------------+----------------+----------------+ 636 * | reserved | 64 637 * +----------------+----------------+----------------+----------------+ 638 * 639 * Must be sent over control ring of the connector which has the index 640 * value of 0: 641 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 642 */ 643 644 struct xendispl_fb_detach_req { 645 uint64_t fb_cookie; 646 }; 647 648 /* 649 * Request configuration set/reset - request to set or reset 650 * the configuration/mode of the display: 651 * 0 1 2 3 octet 652 * +----------------+----------------+----------------+----------------+ 653 * | id | _OP_SET_CONFIG | reserved | 4 654 * +----------------+----------------+----------------+----------------+ 655 * | reserved | 8 656 * +----------------+----------------+----------------+----------------+ 657 * | fb_cookie low 32-bit | 12 658 * +----------------+----------------+----------------+----------------+ 659 * | fb_cookie high 32-bit | 16 660 * +----------------+----------------+----------------+----------------+ 661 * | x | 20 662 * +----------------+----------------+----------------+----------------+ 663 * | y | 24 664 * +----------------+----------------+----------------+----------------+ 665 * | width | 28 666 * +----------------+----------------+----------------+----------------+ 667 * | height | 32 668 * +----------------+----------------+----------------+----------------+ 669 * | bpp | 40 670 * +----------------+----------------+----------------+----------------+ 671 * | reserved | 44 672 * +----------------+----------------+----------------+----------------+ 673 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 674 * +----------------+----------------+----------------+----------------+ 675 * | reserved | 64 676 * +----------------+----------------+----------------+----------------+ 677 * 678 * Pass all zeros to reset, otherwise command is treated as 679 * configuration set. 680 * Framebuffer's cookie defines which framebuffer/dbuf must be 681 * displayed while enabling display (applying configuration). 682 * x, y, width and height are bound by the connector's resolution and must not 683 * exceed it. 684 * 685 * x - uint32_t, starting position in pixels by X axis 686 * y - uint32_t, starting position in pixels by Y axis 687 * width - uint32_t, width in pixels 688 * height - uint32_t, height in pixels 689 * bpp - uint32_t, bits per pixel 690 */ 691 692 struct xendispl_set_config_req { 693 uint64_t fb_cookie; 694 uint32_t x; 695 uint32_t y; 696 uint32_t width; 697 uint32_t height; 698 uint32_t bpp; 699 }; 700 701 /* 702 * Request page flip - request to flip a page identified by the framebuffer 703 * cookie: 704 * 0 1 2 3 octet 705 * +----------------+----------------+----------------+----------------+ 706 * | id | _OP_PG_FLIP | reserved | 4 707 * +----------------+----------------+----------------+----------------+ 708 * | reserved | 8 709 * +----------------+----------------+----------------+----------------+ 710 * | fb_cookie low 32-bit | 12 711 * +----------------+----------------+----------------+----------------+ 712 * | fb_cookie high 32-bit | 16 713 * +----------------+----------------+----------------+----------------+ 714 * | reserved | 20 715 * +----------------+----------------+----------------+----------------+ 716 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 717 * +----------------+----------------+----------------+----------------+ 718 * | reserved | 64 719 * +----------------+----------------+----------------+----------------+ 720 */ 721 722 struct xendispl_page_flip_req { 723 uint64_t fb_cookie; 724 }; 725 726 /* 727 *---------------------------------- Responses -------------------------------- 728 * 729 * All response packets have the same length (64 octets) 730 * 731 * All response packets have common header: 732 * 0 1 2 3 octet 733 * +----------------+----------------+----------------+----------------+ 734 * | id | reserved | 4 735 * +----------------+----------------+----------------+----------------+ 736 * | status | 8 737 * +----------------+----------------+----------------+----------------+ 738 * | reserved | 12 739 * +----------------+----------------+----------------+----------------+ 740 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 741 * +----------------+----------------+----------------+----------------+ 742 * | reserved | 64 743 * +----------------+----------------+----------------+----------------+ 744 * 745 * id - uint16_t, private guest value, echoed from request 746 * status - int32_t, response status, zero on success and -XEN_EXX on failure 747 * 748 *----------------------------------- Events ---------------------------------- 749 * 750 * Events are sent via a shared page allocated by the front and propagated by 751 * evt-event-channel/evt-ring-ref XenStore entries 752 * All event packets have the same length (64 octets) 753 * All event packets have common header: 754 * 0 1 2 3 octet 755 * +----------------+----------------+----------------+----------------+ 756 * | id | type | reserved | 4 757 * +----------------+----------------+----------------+----------------+ 758 * | reserved | 8 759 * +----------------+----------------+----------------+----------------+ 760 * 761 * id - uint16_t, event id, may be used by front 762 * type - uint8_t, type of the event 763 * 764 * 765 * Page flip complete event - event from back to front on page flip completed: 766 * 0 1 2 3 octet 767 * +----------------+----------------+----------------+----------------+ 768 * | id | _EVT_PG_FLIP | reserved | 4 769 * +----------------+----------------+----------------+----------------+ 770 * | reserved | 8 771 * +----------------+----------------+----------------+----------------+ 772 * | fb_cookie low 32-bit | 12 773 * +----------------+----------------+----------------+----------------+ 774 * | fb_cookie high 32-bit | 16 775 * +----------------+----------------+----------------+----------------+ 776 * | reserved | 20 777 * +----------------+----------------+----------------+----------------+ 778 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 779 * +----------------+----------------+----------------+----------------+ 780 * | reserved | 64 781 * +----------------+----------------+----------------+----------------+ 782 */ 783 784 struct xendispl_pg_flip_evt { 785 uint64_t fb_cookie; 786 }; 787 788 struct xendispl_req { 789 uint16_t id; 790 uint8_t operation; 791 uint8_t reserved[5]; 792 union { 793 struct xendispl_dbuf_create_req dbuf_create; 794 struct xendispl_dbuf_destroy_req dbuf_destroy; 795 struct xendispl_fb_attach_req fb_attach; 796 struct xendispl_fb_detach_req fb_detach; 797 struct xendispl_set_config_req set_config; 798 struct xendispl_page_flip_req pg_flip; 799 uint8_t reserved[56]; 800 } op; 801 }; 802 803 struct xendispl_resp { 804 uint16_t id; 805 uint8_t operation; 806 uint8_t reserved; 807 int32_t status; 808 uint8_t reserved1[56]; 809 }; 810 811 struct xendispl_evt { 812 uint16_t id; 813 uint8_t type; 814 uint8_t reserved[5]; 815 union { 816 struct xendispl_pg_flip_evt pg_flip; 817 uint8_t reserved[56]; 818 } op; 819 }; 820 821 DEFINE_RING_TYPES(xen_displif, struct xendispl_req, struct xendispl_resp); 822 823 /* 824 ****************************************************************************** 825 * Back to front events delivery 826 ****************************************************************************** 827 * In order to deliver asynchronous events from back to front a shared page is 828 * allocated by front and its granted reference propagated to back via 829 * XenStore entries (evt-ring-ref/evt-event-channel). 830 * This page has a common header used by both front and back to synchronize 831 * access and control event's ring buffer, while back being a producer of the 832 * events and front being a consumer. The rest of the page after the header 833 * is used for event packets. 834 * 835 * Upon reception of an event(s) front may confirm its reception 836 * for either each event, group of events or none. 837 */ 838 839 struct xendispl_event_page { 840 uint32_t in_cons; 841 uint32_t in_prod; 842 uint8_t reserved[56]; 843 }; 844 845 #define XENDISPL_EVENT_PAGE_SIZE XEN_PAGE_SIZE 846 #define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page)) 847 #define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - XENDISPL_IN_RING_OFFS) 848 #define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct xendispl_evt)) 849 #define XENDISPL_IN_RING(page) \ 850 ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS)) 851 #define XENDISPL_IN_RING_REF(page, idx) \ 852 (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN]) 853 854 #endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */ 855