Home | History | Annotate | Line # | Download | only in io
      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 (at) epam.com>
     27  *          Oleksandr Grytsov <oleksandr_grytsov (at) 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 4096
    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 
    864 /*
    865  * Local variables:
    866  * mode: C
    867  * c-file-style: "BSD"
    868  * c-basic-offset: 4
    869  * tab-width: 4
    870  * indent-tabs-mode: nil
    871  * End:
    872  */
    873