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