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 * unique-id 193 * Values: <string> 194 * 195 * After device instance initialization each connector is assigned a 196 * unique ID, so it can be identified by the backend by this ID. 197 * This can be UUID or such. 198 * 199 * resolution 200 * Values: <width, uint32_t>x<height, uint32_t> 201 * 202 * Width and height of the connector in pixels separated by 203 * XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the 204 * display. 205 * 206 *------------------ Connector Request Transport Parameters ------------------- 207 * 208 * This communication path is used to deliver requests from frontend to backend 209 * and get the corresponding responses from backend to frontend, 210 * set up per connector. 211 * 212 * req-event-channel 213 * Values: <uint32_t> 214 * 215 * The identifier of the Xen connector's control event channel 216 * used to signal activity in the ring buffer. 217 * 218 * req-ring-ref 219 * Values: <uint32_t> 220 * 221 * The Xen grant reference granting permission for the backend to map 222 * a sole page of connector's control ring buffer. 223 * 224 *------------------- Connector Event Transport Parameters -------------------- 225 * 226 * This communication path is used to deliver asynchronous events from backend 227 * to frontend, set up per connector. 228 * 229 * evt-event-channel 230 * Values: <uint32_t> 231 * 232 * The identifier of the Xen connector's event channel 233 * used to signal activity in the ring buffer. 234 * 235 * evt-ring-ref 236 * Values: <uint32_t> 237 * 238 * The Xen grant reference granting permission for the backend to map 239 * a sole page of connector's event ring buffer. 240 */ 241 242 /* 243 ****************************************************************************** 244 * STATE DIAGRAMS 245 ****************************************************************************** 246 * 247 * Tool stack creates front and back state nodes with initial state 248 * XenbusStateInitialising. 249 * Tool stack creates and sets up frontend display configuration 250 * nodes per domain. 251 * 252 *-------------------------------- Normal flow -------------------------------- 253 * 254 * Front Back 255 * ================================= ===================================== 256 * XenbusStateInitialising XenbusStateInitialising 257 * o Query backend device identification 258 * data. 259 * o Open and validate backend device. 260 * | 261 * | 262 * V 263 * XenbusStateInitWait 264 * 265 * o Query frontend configuration 266 * o Allocate and initialize 267 * event channels per configured 268 * connector. 269 * o Publish transport parameters 270 * that will be in effect during 271 * this connection. 272 * | 273 * | 274 * V 275 * XenbusStateInitialised 276 * 277 * o Query frontend transport parameters. 278 * o Connect to the event channels. 279 * | 280 * | 281 * V 282 * XenbusStateConnected 283 * 284 * o Create and initialize OS 285 * virtual display connectors 286 * as per configuration. 287 * | 288 * | 289 * V 290 * XenbusStateConnected 291 * 292 * XenbusStateUnknown 293 * XenbusStateClosed 294 * XenbusStateClosing 295 * o Remove virtual display device 296 * o Remove event channels 297 * | 298 * | 299 * V 300 * XenbusStateClosed 301 * 302 *------------------------------- Recovery flow ------------------------------- 303 * 304 * In case of frontend unrecoverable errors backend handles that as 305 * if frontend goes into the XenbusStateClosed state. 306 * 307 * In case of backend unrecoverable errors frontend tries removing 308 * the virtualized device. If this is possible at the moment of error, 309 * then frontend goes into the XenbusStateInitialising state and is ready for 310 * new connection with backend. If the virtualized device is still in use and 311 * cannot be removed, then frontend goes into the XenbusStateReconfiguring state 312 * until either the virtualized device is removed or backend initiates a new 313 * connection. On the virtualized device removal frontend goes into the 314 * XenbusStateInitialising state. 315 * 316 * Note on XenbusStateReconfiguring state of the frontend: if backend has 317 * unrecoverable errors then frontend cannot send requests to the backend 318 * and thus cannot provide functionality of the virtualized device anymore. 319 * After backend is back to normal the virtualized device may still hold some 320 * state: configuration in use, allocated buffers, client application state etc. 321 * In most cases, this will require frontend to implement complex recovery 322 * reconnect logic. Instead, by going into XenbusStateReconfiguring state, 323 * frontend will make sure no new clients of the virtualized device are 324 * accepted, allow existing client(s) to exit gracefully by signaling error 325 * state etc. 326 * Once all the clients are gone frontend can reinitialize the virtualized 327 * device and get into XenbusStateInitialising state again signaling the 328 * backend that a new connection can be made. 329 * 330 * There are multiple conditions possible under which frontend will go from 331 * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS 332 * specific. For example: 333 * 1. The underlying OS framework may provide callbacks to signal that the last 334 * client of the virtualized device has gone and the device can be removed 335 * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue) 336 * to periodically check if this is the right time to re-try removal of 337 * the virtualized device. 338 * 3. By any other means. 339 * 340 ****************************************************************************** 341 * REQUEST CODES 342 ****************************************************************************** 343 * Request codes [0; 15] are reserved and must not be used 344 */ 345 346 #define XENDISPL_OP_DBUF_CREATE 0x10 347 #define XENDISPL_OP_DBUF_DESTROY 0x11 348 #define XENDISPL_OP_FB_ATTACH 0x12 349 #define XENDISPL_OP_FB_DETACH 0x13 350 #define XENDISPL_OP_SET_CONFIG 0x14 351 #define XENDISPL_OP_PG_FLIP 0x15 352 353 /* 354 ****************************************************************************** 355 * EVENT CODES 356 ****************************************************************************** 357 */ 358 #define XENDISPL_EVT_PG_FLIP 0x00 359 360 /* 361 ****************************************************************************** 362 * XENSTORE FIELD AND PATH NAME STRINGS, HELPERS 363 ****************************************************************************** 364 */ 365 #define XENDISPL_DRIVER_NAME "vdispl" 366 367 #define XENDISPL_LIST_SEPARATOR "," 368 #define XENDISPL_RESOLUTION_SEPARATOR "x" 369 370 #define XENDISPL_FIELD_BE_VERSIONS "versions" 371 #define XENDISPL_FIELD_FE_VERSION "version" 372 #define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref" 373 #define XENDISPL_FIELD_REQ_CHANNEL "req-event-channel" 374 #define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref" 375 #define XENDISPL_FIELD_EVT_CHANNEL "evt-event-channel" 376 #define XENDISPL_FIELD_RESOLUTION "resolution" 377 #define XENDISPL_FIELD_BE_ALLOC "be-alloc" 378 #define XENDISPL_FIELD_UNIQUE_ID "unique-id" 379 380 /* 381 ****************************************************************************** 382 * STATUS RETURN CODES 383 ****************************************************************************** 384 * 385 * Status return code is zero on success and -XEN_EXX on failure. 386 * 387 ****************************************************************************** 388 * Assumptions 389 ****************************************************************************** 390 * o usage of grant reference 0 as invalid grant reference: 391 * grant reference 0 is valid, but never exposed to a PV driver, 392 * because of the fact it is already in use/reserved by the PV console. 393 * o all references in this document to page sizes must be treated 394 * as pages of size XEN_PAGE_SIZE unless otherwise noted. 395 * 396 ****************************************************************************** 397 * Description of the protocol between frontend and backend driver 398 ****************************************************************************** 399 * 400 * The two halves of a Para-virtual display driver communicate with 401 * each other using shared pages and event channels. 402 * Shared page contains a ring with request/response packets. 403 * 404 * All reserved fields in the structures below must be 0. 405 * Display buffers's cookie of value 0 is treated as invalid. 406 * Framebuffer's cookie of value 0 is treated as invalid. 407 * 408 * For all request/response/event packets that use cookies: 409 * dbuf_cookie - uint64_t, unique to guest domain value used by the backend 410 * to map remote display buffer to its local one 411 * fb_cookie - uint64_t, unique to guest domain value used by the backend 412 * to map remote framebuffer to its local one 413 * 414 *---------------------------------- Requests --------------------------------- 415 * 416 * All requests/responses, which are not connector specific, must be sent over 417 * control ring of the connector which has the index value of 0: 418 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 419 * 420 * All request packets have the same length (64 octets) 421 * All request packets have common header: 422 * 0 1 2 3 octet 423 * +----------------+----------------+----------------+----------------+ 424 * | id | operation | reserved | 4 425 * +----------------+----------------+----------------+----------------+ 426 * | reserved | 8 427 * +----------------+----------------+----------------+----------------+ 428 * id - uint16_t, private guest value, echoed in response 429 * operation - uint8_t, operation code, XENDISPL_OP_??? 430 * 431 * Request dbuf creation - request creation of a display buffer. 432 * 0 1 2 3 octet 433 * +----------------+----------------+----------------+----------------+ 434 * | id |_OP_DBUF_CREATE | reserved | 4 435 * +----------------+----------------+----------------+----------------+ 436 * | reserved | 8 437 * +----------------+----------------+----------------+----------------+ 438 * | dbuf_cookie low 32-bit | 12 439 * +----------------+----------------+----------------+----------------+ 440 * | dbuf_cookie high 32-bit | 16 441 * +----------------+----------------+----------------+----------------+ 442 * | width | 20 443 * +----------------+----------------+----------------+----------------+ 444 * | height | 24 445 * +----------------+----------------+----------------+----------------+ 446 * | bpp | 28 447 * +----------------+----------------+----------------+----------------+ 448 * | buffer_sz | 32 449 * +----------------+----------------+----------------+----------------+ 450 * | flags | 36 451 * +----------------+----------------+----------------+----------------+ 452 * | gref_directory | 40 453 * +----------------+----------------+----------------+----------------+ 454 * | reserved | 44 455 * +----------------+----------------+----------------+----------------+ 456 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 457 * +----------------+----------------+----------------+----------------+ 458 * | reserved | 64 459 * +----------------+----------------+----------------+----------------+ 460 * 461 * Must be sent over control ring of the connector which has the index 462 * value of 0: 463 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 464 * All unused bits in flags field must be set to 0. 465 * 466 * An attempt to create multiple display buffers with the same dbuf_cookie is 467 * an error. dbuf_cookie can be re-used after destroying the corresponding 468 * display buffer. 469 * 470 * Width and height of the display buffers can be smaller, equal or bigger 471 * than the connector's resolution. Depth/pixel format of the individual 472 * buffers can differ as well. 473 * 474 * width - uint32_t, width in pixels 475 * height - uint32_t, height in pixels 476 * bpp - uint32_t, bits per pixel 477 * buffer_sz - uint32_t, buffer size to be allocated, octets 478 * flags - uint32_t, flags of the operation 479 * o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested 480 * to allocate the buffer with the parameters provided in this request. 481 * Page directory is handled as follows: 482 * Frontend on request: 483 * o allocates pages for the directory (gref_directory, 484 * gref_dir_next_page(s) 485 * o grants permissions for the pages of the directory to the backend 486 * o sets gref_dir_next_page fields 487 * Backend on response: 488 * o grants permissions for the pages of the buffer allocated to 489 * the frontend 490 * o fills in page directory with grant references 491 * (gref[] in struct xendispl_page_directory) 492 * gref_directory - grant_ref_t, a reference to the first shared page 493 * describing shared buffer references. At least one page exists. If shared 494 * buffer size (buffer_sz) exceeds what can be addressed by this single page, 495 * then reference to the next page must be supplied (see gref_dir_next_page 496 * below) 497 */ 498 499 #define XENDISPL_DBUF_FLG_REQ_ALLOC (1 << 0) 500 501 struct xendispl_dbuf_create_req { 502 uint64_t dbuf_cookie; 503 uint32_t width; 504 uint32_t height; 505 uint32_t bpp; 506 uint32_t buffer_sz; 507 uint32_t flags; 508 grant_ref_t gref_directory; 509 }; 510 511 /* 512 * Shared page for XENDISPL_OP_DBUF_CREATE buffer descriptor (gref_directory in 513 * the request) employs a list of pages, describing all pages of the shared 514 * data buffer: 515 * 0 1 2 3 octet 516 * +----------------+----------------+----------------+----------------+ 517 * | gref_dir_next_page | 4 518 * +----------------+----------------+----------------+----------------+ 519 * | gref[0] | 8 520 * +----------------+----------------+----------------+----------------+ 521 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 522 * +----------------+----------------+----------------+----------------+ 523 * | gref[i] | i*4+8 524 * +----------------+----------------+----------------+----------------+ 525 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 526 * +----------------+----------------+----------------+----------------+ 527 * | gref[N - 1] | N*4+8 528 * +----------------+----------------+----------------+----------------+ 529 * 530 * gref_dir_next_page - grant_ref_t, reference to the next page describing 531 * page directory. Must be 0 if there are no more pages in the list. 532 * gref[i] - grant_ref_t, reference to a shared page of the buffer 533 * allocated at XENDISPL_OP_DBUF_CREATE 534 * 535 * Number of grant_ref_t entries in the whole page directory is not 536 * passed, but instead can be calculated as: 537 * num_grefs_total = (XENDISPL_OP_DBUF_CREATE.buffer_sz + XEN_PAGE_SIZE - 1) / 538 * XEN_PAGE_SIZE 539 */ 540 541 struct xendispl_page_directory { 542 grant_ref_t gref_dir_next_page; 543 grant_ref_t gref[1]; /* Variable length */ 544 }; 545 546 /* 547 * Request dbuf destruction - destroy a previously allocated display buffer: 548 * 0 1 2 3 octet 549 * +----------------+----------------+----------------+----------------+ 550 * | id |_OP_DBUF_DESTROY| reserved | 4 551 * +----------------+----------------+----------------+----------------+ 552 * | reserved | 8 553 * +----------------+----------------+----------------+----------------+ 554 * | dbuf_cookie low 32-bit | 12 555 * +----------------+----------------+----------------+----------------+ 556 * | dbuf_cookie high 32-bit | 16 557 * +----------------+----------------+----------------+----------------+ 558 * | reserved | 20 559 * +----------------+----------------+----------------+----------------+ 560 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 561 * +----------------+----------------+----------------+----------------+ 562 * | reserved | 64 563 * +----------------+----------------+----------------+----------------+ 564 * 565 * Must be sent over control ring of the connector which has the index 566 * value of 0: 567 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 568 */ 569 570 struct xendispl_dbuf_destroy_req { 571 uint64_t dbuf_cookie; 572 }; 573 574 /* 575 * Request framebuffer attachment - request attachment of a framebuffer to 576 * previously created display buffer. 577 * 0 1 2 3 octet 578 * +----------------+----------------+----------------+----------------+ 579 * | id | _OP_FB_ATTACH | reserved | 4 580 * +----------------+----------------+----------------+----------------+ 581 * | reserved | 8 582 * +----------------+----------------+----------------+----------------+ 583 * | dbuf_cookie low 32-bit | 12 584 * +----------------+----------------+----------------+----------------+ 585 * | dbuf_cookie high 32-bit | 16 586 * +----------------+----------------+----------------+----------------+ 587 * | fb_cookie low 32-bit | 20 588 * +----------------+----------------+----------------+----------------+ 589 * | fb_cookie high 32-bit | 24 590 * +----------------+----------------+----------------+----------------+ 591 * | width | 28 592 * +----------------+----------------+----------------+----------------+ 593 * | height | 32 594 * +----------------+----------------+----------------+----------------+ 595 * | pixel_format | 36 596 * +----------------+----------------+----------------+----------------+ 597 * | reserved | 40 598 * +----------------+----------------+----------------+----------------+ 599 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 600 * +----------------+----------------+----------------+----------------+ 601 * | reserved | 64 602 * +----------------+----------------+----------------+----------------+ 603 * 604 * Must be sent over control ring of the connector which has the index 605 * value of 0: 606 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 607 * Width and height can be smaller, equal or bigger than the connector's 608 * resolution. 609 * 610 * An attempt to create multiple frame buffers with the same fb_cookie is 611 * an error. fb_cookie can be re-used after destroying the corresponding 612 * frame buffer. 613 * 614 * width - uint32_t, width in pixels 615 * height - uint32_t, height in pixels 616 * pixel_format - uint32_t, pixel format of the framebuffer, FOURCC code 617 */ 618 619 struct xendispl_fb_attach_req { 620 uint64_t dbuf_cookie; 621 uint64_t fb_cookie; 622 uint32_t width; 623 uint32_t height; 624 uint32_t pixel_format; 625 }; 626 627 /* 628 * Request framebuffer detach - detach a previously 629 * attached framebuffer from the display buffer in request: 630 * 0 1 2 3 octet 631 * +----------------+----------------+----------------+----------------+ 632 * | id | _OP_FB_DETACH | reserved | 4 633 * +----------------+----------------+----------------+----------------+ 634 * | reserved | 8 635 * +----------------+----------------+----------------+----------------+ 636 * | fb_cookie low 32-bit | 12 637 * +----------------+----------------+----------------+----------------+ 638 * | fb_cookie high 32-bit | 16 639 * +----------------+----------------+----------------+----------------+ 640 * | reserved | 20 641 * +----------------+----------------+----------------+----------------+ 642 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 643 * +----------------+----------------+----------------+----------------+ 644 * | reserved | 64 645 * +----------------+----------------+----------------+----------------+ 646 * 647 * Must be sent over control ring of the connector which has the index 648 * value of 0: 649 * /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref 650 */ 651 652 struct xendispl_fb_detach_req { 653 uint64_t fb_cookie; 654 }; 655 656 /* 657 * Request configuration set/reset - request to set or reset 658 * the configuration/mode of the display: 659 * 0 1 2 3 octet 660 * +----------------+----------------+----------------+----------------+ 661 * | id | _OP_SET_CONFIG | reserved | 4 662 * +----------------+----------------+----------------+----------------+ 663 * | reserved | 8 664 * +----------------+----------------+----------------+----------------+ 665 * | fb_cookie low 32-bit | 12 666 * +----------------+----------------+----------------+----------------+ 667 * | fb_cookie high 32-bit | 16 668 * +----------------+----------------+----------------+----------------+ 669 * | x | 20 670 * +----------------+----------------+----------------+----------------+ 671 * | y | 24 672 * +----------------+----------------+----------------+----------------+ 673 * | width | 28 674 * +----------------+----------------+----------------+----------------+ 675 * | height | 32 676 * +----------------+----------------+----------------+----------------+ 677 * | bpp | 40 678 * +----------------+----------------+----------------+----------------+ 679 * | reserved | 44 680 * +----------------+----------------+----------------+----------------+ 681 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 682 * +----------------+----------------+----------------+----------------+ 683 * | reserved | 64 684 * +----------------+----------------+----------------+----------------+ 685 * 686 * Pass all zeros to reset, otherwise command is treated as 687 * configuration set. 688 * Framebuffer's cookie defines which framebuffer/dbuf must be 689 * displayed while enabling display (applying configuration). 690 * x, y, width and height are bound by the connector's resolution and must not 691 * exceed it. 692 * 693 * x - uint32_t, starting position in pixels by X axis 694 * y - uint32_t, starting position in pixels by Y axis 695 * width - uint32_t, width in pixels 696 * height - uint32_t, height in pixels 697 * bpp - uint32_t, bits per pixel 698 */ 699 700 struct xendispl_set_config_req { 701 uint64_t fb_cookie; 702 uint32_t x; 703 uint32_t y; 704 uint32_t width; 705 uint32_t height; 706 uint32_t bpp; 707 }; 708 709 /* 710 * Request page flip - request to flip a page identified by the framebuffer 711 * cookie: 712 * 0 1 2 3 octet 713 * +----------------+----------------+----------------+----------------+ 714 * | id | _OP_PG_FLIP | reserved | 4 715 * +----------------+----------------+----------------+----------------+ 716 * | reserved | 8 717 * +----------------+----------------+----------------+----------------+ 718 * | fb_cookie low 32-bit | 12 719 * +----------------+----------------+----------------+----------------+ 720 * | fb_cookie high 32-bit | 16 721 * +----------------+----------------+----------------+----------------+ 722 * | reserved | 20 723 * +----------------+----------------+----------------+----------------+ 724 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 725 * +----------------+----------------+----------------+----------------+ 726 * | reserved | 64 727 * +----------------+----------------+----------------+----------------+ 728 */ 729 730 struct xendispl_page_flip_req { 731 uint64_t fb_cookie; 732 }; 733 734 /* 735 *---------------------------------- Responses -------------------------------- 736 * 737 * All response packets have the same length (64 octets) 738 * 739 * All response packets have common header: 740 * 0 1 2 3 octet 741 * +----------------+----------------+----------------+----------------+ 742 * | id | reserved | 4 743 * +----------------+----------------+----------------+----------------+ 744 * | status | 8 745 * +----------------+----------------+----------------+----------------+ 746 * | reserved | 12 747 * +----------------+----------------+----------------+----------------+ 748 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 749 * +----------------+----------------+----------------+----------------+ 750 * | reserved | 64 751 * +----------------+----------------+----------------+----------------+ 752 * 753 * id - uint16_t, private guest value, echoed from request 754 * status - int32_t, response status, zero on success and -XEN_EXX on failure 755 * 756 *----------------------------------- Events ---------------------------------- 757 * 758 * Events are sent via a shared page allocated by the front and propagated by 759 * evt-event-channel/evt-ring-ref XenStore entries 760 * All event packets have the same length (64 octets) 761 * All event packets have common header: 762 * 0 1 2 3 octet 763 * +----------------+----------------+----------------+----------------+ 764 * | id | type | reserved | 4 765 * +----------------+----------------+----------------+----------------+ 766 * | reserved | 8 767 * +----------------+----------------+----------------+----------------+ 768 * 769 * id - uint16_t, event id, may be used by front 770 * type - uint8_t, type of the event 771 * 772 * 773 * Page flip complete event - event from back to front on page flip completed: 774 * 0 1 2 3 octet 775 * +----------------+----------------+----------------+----------------+ 776 * | id | _EVT_PG_FLIP | reserved | 4 777 * +----------------+----------------+----------------+----------------+ 778 * | reserved | 8 779 * +----------------+----------------+----------------+----------------+ 780 * | fb_cookie low 32-bit | 12 781 * +----------------+----------------+----------------+----------------+ 782 * | fb_cookie high 32-bit | 16 783 * +----------------+----------------+----------------+----------------+ 784 * | reserved | 20 785 * +----------------+----------------+----------------+----------------+ 786 * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/| 787 * +----------------+----------------+----------------+----------------+ 788 * | reserved | 64 789 * +----------------+----------------+----------------+----------------+ 790 */ 791 792 struct xendispl_pg_flip_evt { 793 uint64_t fb_cookie; 794 }; 795 796 struct xendispl_req { 797 uint16_t id; 798 uint8_t operation; 799 uint8_t reserved[5]; 800 union { 801 struct xendispl_dbuf_create_req dbuf_create; 802 struct xendispl_dbuf_destroy_req dbuf_destroy; 803 struct xendispl_fb_attach_req fb_attach; 804 struct xendispl_fb_detach_req fb_detach; 805 struct xendispl_set_config_req set_config; 806 struct xendispl_page_flip_req pg_flip; 807 uint8_t reserved[56]; 808 } op; 809 }; 810 811 struct xendispl_resp { 812 uint16_t id; 813 uint8_t operation; 814 uint8_t reserved; 815 int32_t status; 816 uint8_t reserved1[56]; 817 }; 818 819 struct xendispl_evt { 820 uint16_t id; 821 uint8_t type; 822 uint8_t reserved[5]; 823 union { 824 struct xendispl_pg_flip_evt pg_flip; 825 uint8_t reserved[56]; 826 } op; 827 }; 828 829 DEFINE_RING_TYPES(xen_displif, struct xendispl_req, struct xendispl_resp); 830 831 /* 832 ****************************************************************************** 833 * Back to front events delivery 834 ****************************************************************************** 835 * In order to deliver asynchronous events from back to front a shared page is 836 * allocated by front and its granted reference propagated to back via 837 * XenStore entries (evt-ring-ref/evt-event-channel). 838 * This page has a common header used by both front and back to synchronize 839 * access and control event's ring buffer, while back being a producer of the 840 * events and front being a consumer. The rest of the page after the header 841 * is used for event packets. 842 * 843 * Upon reception of an event(s) front may confirm its reception 844 * for either each event, group of events or none. 845 */ 846 847 struct xendispl_event_page { 848 uint32_t in_cons; 849 uint32_t in_prod; 850 uint8_t reserved[56]; 851 }; 852 853 #define XENDISPL_EVENT_PAGE_SIZE XEN_PAGE_SIZE 854 #define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page)) 855 #define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - XENDISPL_IN_RING_OFFS) 856 #define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct xendispl_evt)) 857 #define XENDISPL_IN_RING(page) \ 858 ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS)) 859 #define XENDISPL_IN_RING_REF(page, idx) \ 860 (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN]) 861 862 #endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */ 863