Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: MIT */
0002 /******************************************************************************
0003  * displif.h
0004  *
0005  * Unified display device I/O interface for Xen guest OSes.
0006  *
0007  * Copyright (C) 2016-2017 EPAM Systems Inc.
0008  *
0009  * Authors: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
0010  *          Oleksandr Grytsov <oleksandr_grytsov@epam.com>
0011  */
0012 
0013 #ifndef __XEN_PUBLIC_IO_DISPLIF_H__
0014 #define __XEN_PUBLIC_IO_DISPLIF_H__
0015 
0016 #include "ring.h"
0017 #include "../grant_table.h"
0018 
0019 /*
0020  ******************************************************************************
0021  *                           Protocol version
0022  ******************************************************************************
0023  */
0024 #define XENDISPL_PROTOCOL_VERSION   "2"
0025 #define XENDISPL_PROTOCOL_VERSION_INT    2
0026 
0027 /*
0028  ******************************************************************************
0029  *                  Main features provided by the protocol
0030  ******************************************************************************
0031  * This protocol aims to provide a unified protocol which fits more
0032  * sophisticated use-cases than a framebuffer device can handle. At the
0033  * moment basic functionality is supported with the intention to be extended:
0034  *  o multiple dynamically allocated/destroyed framebuffers
0035  *  o buffers of arbitrary sizes
0036  *  o buffer allocation at either back or front end
0037  *  o better configuration options including multiple display support
0038  *
0039  * Note: existing fbif can be used together with displif running at the
0040  * same time, e.g. on Linux one provides framebuffer and another DRM/KMS
0041  *
0042  * Note: display resolution (XenStore's "resolution" property) defines
0043  * visible area of the virtual display. At the same time resolution of
0044  * the display and frame buffers may differ: buffers can be smaller, equal
0045  * or bigger than the visible area. This is to enable use-cases, where backend
0046  * may do some post-processing of the display and frame buffers supplied,
0047  * e.g. those buffers can be just a part of the final composition.
0048  *
0049  ******************************************************************************
0050  *                        Direction of improvements
0051  ******************************************************************************
0052  * Future extensions to the existing protocol may include:
0053  *  o display/connector cloning
0054  *  o allocation of objects other than display buffers
0055  *  o plane/overlay support
0056  *  o scaling support
0057  *  o rotation support
0058  *
0059  ******************************************************************************
0060  *                  Feature and Parameter Negotiation
0061  ******************************************************************************
0062  *
0063  * Front->back notifications: when enqueuing a new request, sending a
0064  * notification can be made conditional on xendispl_req (i.e., the generic
0065  * hold-off mechanism provided by the ring macros). Backends must set
0066  * xendispl_req appropriately (e.g., using RING_FINAL_CHECK_FOR_REQUESTS()).
0067  *
0068  * Back->front notifications: when enqueuing a new response, sending a
0069  * notification can be made conditional on xendispl_resp (i.e., the generic
0070  * hold-off mechanism provided by the ring macros). Frontends must set
0071  * xendispl_resp appropriately (e.g., using RING_FINAL_CHECK_FOR_RESPONSES()).
0072  *
0073  * The two halves of a para-virtual display driver utilize nodes within
0074  * XenStore to communicate capabilities and to negotiate operating parameters.
0075  * This section enumerates these nodes which reside in the respective front and
0076  * backend portions of XenStore, following the XenBus convention.
0077  *
0078  * All data in XenStore is stored as strings. Nodes specifying numeric
0079  * values are encoded in decimal. Integer value ranges listed below are
0080  * expressed as fixed sized integer types capable of storing the conversion
0081  * of a properly formated node string, without loss of information.
0082  *
0083  ******************************************************************************
0084  *                        Example configuration
0085  ******************************************************************************
0086  *
0087  * Note: depending on the use-case backend can expose more display connectors
0088  * than the underlying HW physically has by employing SW graphics compositors
0089  *
0090  * This is an example of backend and frontend configuration:
0091  *
0092  *--------------------------------- Backend -----------------------------------
0093  *
0094  * /local/domain/0/backend/vdispl/1/0/frontend-id = "1"
0095  * /local/domain/0/backend/vdispl/1/0/frontend = "/local/domain/1/device/vdispl/0"
0096  * /local/domain/0/backend/vdispl/1/0/state = "4"
0097  * /local/domain/0/backend/vdispl/1/0/versions = "1,2"
0098  *
0099  *--------------------------------- Frontend ----------------------------------
0100  *
0101  * /local/domain/1/device/vdispl/0/backend-id = "0"
0102  * /local/domain/1/device/vdispl/0/backend = "/local/domain/0/backend/vdispl/1/0"
0103  * /local/domain/1/device/vdispl/0/state = "4"
0104  * /local/domain/1/device/vdispl/0/version = "1"
0105  * /local/domain/1/device/vdispl/0/be-alloc = "1"
0106  *
0107  *-------------------------- Connector 0 configuration ------------------------
0108  *
0109  * /local/domain/1/device/vdispl/0/0/resolution = "1920x1080"
0110  * /local/domain/1/device/vdispl/0/0/req-ring-ref = "2832"
0111  * /local/domain/1/device/vdispl/0/0/req-event-channel = "15"
0112  * /local/domain/1/device/vdispl/0/0/evt-ring-ref = "387"
0113  * /local/domain/1/device/vdispl/0/0/evt-event-channel = "16"
0114  *
0115  *-------------------------- Connector 1 configuration ------------------------
0116  *
0117  * /local/domain/1/device/vdispl/0/1/resolution = "800x600"
0118  * /local/domain/1/device/vdispl/0/1/req-ring-ref = "2833"
0119  * /local/domain/1/device/vdispl/0/1/req-event-channel = "17"
0120  * /local/domain/1/device/vdispl/0/1/evt-ring-ref = "388"
0121  * /local/domain/1/device/vdispl/0/1/evt-event-channel = "18"
0122  *
0123  ******************************************************************************
0124  *                            Backend XenBus Nodes
0125  ******************************************************************************
0126  *
0127  *----------------------------- Protocol version ------------------------------
0128  *
0129  * versions
0130  *      Values:         <string>
0131  *
0132  *      List of XENDISPL_LIST_SEPARATOR separated protocol versions supported
0133  *      by the backend. For example "1,2,3".
0134  *
0135  ******************************************************************************
0136  *                            Frontend XenBus Nodes
0137  ******************************************************************************
0138  *
0139  *-------------------------------- Addressing ---------------------------------
0140  *
0141  * dom-id
0142  *      Values:         <uint16_t>
0143  *
0144  *      Domain identifier.
0145  *
0146  * dev-id
0147  *      Values:         <uint16_t>
0148  *
0149  *      Device identifier.
0150  *
0151  * conn-idx
0152  *      Values:         <uint8_t>
0153  *
0154  *      Zero based contigous index of the connector.
0155  *      /local/domain/<dom-id>/device/vdispl/<dev-id>/<conn-idx>/...
0156  *
0157  *----------------------------- Protocol version ------------------------------
0158  *
0159  * version
0160  *      Values:         <string>
0161  *
0162  *      Protocol version, chosen among the ones supported by the backend.
0163  *
0164  *------------------------- Backend buffer allocation -------------------------
0165  *
0166  * be-alloc
0167  *      Values:         "0", "1"
0168  *
0169  *      If value is set to "1", then backend can be a buffer provider/allocator
0170  *      for this domain during XENDISPL_OP_DBUF_CREATE operation (see below
0171  *      for negotiation).
0172  *      If value is not "1" or omitted frontend must allocate buffers itself.
0173  *
0174  *----------------------------- Connector settings ----------------------------
0175  *
0176  * unique-id
0177  *      Values:         <string>
0178  *
0179  *      After device instance initialization each connector is assigned a
0180  *      unique ID, so it can be identified by the backend by this ID.
0181  *      This can be UUID or such.
0182  *
0183  * resolution
0184  *      Values:         <width, uint32_t>x<height, uint32_t>
0185  *
0186  *      Width and height of the connector in pixels separated by
0187  *      XENDISPL_RESOLUTION_SEPARATOR. This defines visible area of the
0188  *      display.
0189  *      If backend provides extended display identification data (EDID) with
0190  *      XENDISPL_OP_GET_EDID request then EDID values must take precedence
0191  *      over the resolutions defined here.
0192  *
0193  *------------------ Connector Request Transport Parameters -------------------
0194  *
0195  * This communication path is used to deliver requests from frontend to backend
0196  * and get the corresponding responses from backend to frontend,
0197  * set up per connector.
0198  *
0199  * req-event-channel
0200  *      Values:         <uint32_t>
0201  *
0202  *      The identifier of the Xen connector's control event channel
0203  *      used to signal activity in the ring buffer.
0204  *
0205  * req-ring-ref
0206  *      Values:         <uint32_t>
0207  *
0208  *      The Xen grant reference granting permission for the backend to map
0209  *      a sole page of connector's control ring buffer.
0210  *
0211  *------------------- Connector Event Transport Parameters --------------------
0212  *
0213  * This communication path is used to deliver asynchronous events from backend
0214  * to frontend, set up per connector.
0215  *
0216  * evt-event-channel
0217  *      Values:         <uint32_t>
0218  *
0219  *      The identifier of the Xen connector's event channel
0220  *      used to signal activity in the ring buffer.
0221  *
0222  * evt-ring-ref
0223  *      Values:         <uint32_t>
0224  *
0225  *      The Xen grant reference granting permission for the backend to map
0226  *      a sole page of connector's event ring buffer.
0227  */
0228 
0229 /*
0230  ******************************************************************************
0231  *                               STATE DIAGRAMS
0232  ******************************************************************************
0233  *
0234  * Tool stack creates front and back state nodes with initial state
0235  * XenbusStateInitialising.
0236  * Tool stack creates and sets up frontend display configuration
0237  * nodes per domain.
0238  *
0239  *-------------------------------- Normal flow --------------------------------
0240  *
0241  * Front                                Back
0242  * =================================    =====================================
0243  * XenbusStateInitialising              XenbusStateInitialising
0244  *                                       o Query backend device identification
0245  *                                         data.
0246  *                                       o Open and validate backend device.
0247  *                                                |
0248  *                                                |
0249  *                                                V
0250  *                                      XenbusStateInitWait
0251  *
0252  * o Query frontend configuration
0253  * o Allocate and initialize
0254  *   event channels per configured
0255  *   connector.
0256  * o Publish transport parameters
0257  *   that will be in effect during
0258  *   this connection.
0259  *              |
0260  *              |
0261  *              V
0262  * XenbusStateInitialised
0263  *
0264  *                                       o Query frontend transport parameters.
0265  *                                       o Connect to the event channels.
0266  *                                                |
0267  *                                                |
0268  *                                                V
0269  *                                      XenbusStateConnected
0270  *
0271  *  o Create and initialize OS
0272  *    virtual display connectors
0273  *    as per configuration.
0274  *              |
0275  *              |
0276  *              V
0277  * XenbusStateConnected
0278  *
0279  *                                      XenbusStateUnknown
0280  *                                      XenbusStateClosed
0281  *                                      XenbusStateClosing
0282  * o Remove virtual display device
0283  * o Remove event channels
0284  *              |
0285  *              |
0286  *              V
0287  * XenbusStateClosed
0288  *
0289  *------------------------------- Recovery flow -------------------------------
0290  *
0291  * In case of frontend unrecoverable errors backend handles that as
0292  * if frontend goes into the XenbusStateClosed state.
0293  *
0294  * In case of backend unrecoverable errors frontend tries removing
0295  * the virtualized device. If this is possible at the moment of error,
0296  * then frontend goes into the XenbusStateInitialising state and is ready for
0297  * new connection with backend. If the virtualized device is still in use and
0298  * cannot be removed, then frontend goes into the XenbusStateReconfiguring state
0299  * until either the virtualized device is removed or backend initiates a new
0300  * connection. On the virtualized device removal frontend goes into the
0301  * XenbusStateInitialising state.
0302  *
0303  * Note on XenbusStateReconfiguring state of the frontend: if backend has
0304  * unrecoverable errors then frontend cannot send requests to the backend
0305  * and thus cannot provide functionality of the virtualized device anymore.
0306  * After backend is back to normal the virtualized device may still hold some
0307  * state: configuration in use, allocated buffers, client application state etc.
0308  * In most cases, this will require frontend to implement complex recovery
0309  * reconnect logic. Instead, by going into XenbusStateReconfiguring state,
0310  * frontend will make sure no new clients of the virtualized device are
0311  * accepted, allow existing client(s) to exit gracefully by signaling error
0312  * state etc.
0313  * Once all the clients are gone frontend can reinitialize the virtualized
0314  * device and get into XenbusStateInitialising state again signaling the
0315  * backend that a new connection can be made.
0316  *
0317  * There are multiple conditions possible under which frontend will go from
0318  * XenbusStateReconfiguring into XenbusStateInitialising, some of them are OS
0319  * specific. For example:
0320  * 1. The underlying OS framework may provide callbacks to signal that the last
0321  *    client of the virtualized device has gone and the device can be removed
0322  * 2. Frontend can schedule a deferred work (timer/tasklet/workqueue)
0323  *    to periodically check if this is the right time to re-try removal of
0324  *    the virtualized device.
0325  * 3. By any other means.
0326  *
0327  ******************************************************************************
0328  *                             REQUEST CODES
0329  ******************************************************************************
0330  * Request codes [0; 15] are reserved and must not be used
0331  */
0332 
0333 #define XENDISPL_OP_DBUF_CREATE     0x10
0334 #define XENDISPL_OP_DBUF_DESTROY    0x11
0335 #define XENDISPL_OP_FB_ATTACH       0x12
0336 #define XENDISPL_OP_FB_DETACH       0x13
0337 #define XENDISPL_OP_SET_CONFIG      0x14
0338 #define XENDISPL_OP_PG_FLIP     0x15
0339 /* The below command is available in protocol version 2 and above. */
0340 #define XENDISPL_OP_GET_EDID        0x16
0341 
0342 /*
0343  ******************************************************************************
0344  *                                 EVENT CODES
0345  ******************************************************************************
0346  */
0347 #define XENDISPL_EVT_PG_FLIP        0x00
0348 
0349 /*
0350  ******************************************************************************
0351  *               XENSTORE FIELD AND PATH NAME STRINGS, HELPERS
0352  ******************************************************************************
0353  */
0354 #define XENDISPL_DRIVER_NAME        "vdispl"
0355 
0356 #define XENDISPL_LIST_SEPARATOR     ","
0357 #define XENDISPL_RESOLUTION_SEPARATOR   "x"
0358 
0359 #define XENDISPL_FIELD_BE_VERSIONS  "versions"
0360 #define XENDISPL_FIELD_FE_VERSION   "version"
0361 #define XENDISPL_FIELD_REQ_RING_REF "req-ring-ref"
0362 #define XENDISPL_FIELD_REQ_CHANNEL  "req-event-channel"
0363 #define XENDISPL_FIELD_EVT_RING_REF "evt-ring-ref"
0364 #define XENDISPL_FIELD_EVT_CHANNEL  "evt-event-channel"
0365 #define XENDISPL_FIELD_RESOLUTION   "resolution"
0366 #define XENDISPL_FIELD_BE_ALLOC     "be-alloc"
0367 #define XENDISPL_FIELD_UNIQUE_ID    "unique-id"
0368 
0369 #define XENDISPL_EDID_BLOCK_SIZE    128
0370 #define XENDISPL_EDID_BLOCK_COUNT   256
0371 #define XENDISPL_EDID_MAX_SIZE      (XENDISPL_EDID_BLOCK_SIZE * XENDISPL_EDID_BLOCK_COUNT)
0372 
0373 /*
0374  ******************************************************************************
0375  *                          STATUS RETURN CODES
0376  ******************************************************************************
0377  *
0378  * Status return code is zero on success and -XEN_EXX on failure.
0379  *
0380  ******************************************************************************
0381  *                              Assumptions
0382  ******************************************************************************
0383  * o usage of grant reference 0 as invalid grant reference:
0384  *   grant reference 0 is valid, but never exposed to a PV driver,
0385  *   because of the fact it is already in use/reserved by the PV console.
0386  * o all references in this document to page sizes must be treated
0387  *   as pages of size XEN_PAGE_SIZE unless otherwise noted.
0388  *
0389  ******************************************************************************
0390  *       Description of the protocol between frontend and backend driver
0391  ******************************************************************************
0392  *
0393  * The two halves of a Para-virtual display driver communicate with
0394  * each other using shared pages and event channels.
0395  * Shared page contains a ring with request/response packets.
0396  *
0397  * All reserved fields in the structures below must be 0.
0398  * Display buffers's cookie of value 0 is treated as invalid.
0399  * Framebuffer's cookie of value 0 is treated as invalid.
0400  *
0401  * For all request/response/event packets that use cookies:
0402  *   dbuf_cookie - uint64_t, unique to guest domain value used by the backend
0403  *     to map remote display buffer to its local one
0404  *   fb_cookie - uint64_t, unique to guest domain value used by the backend
0405  *     to map remote framebuffer to its local one
0406  *
0407  *---------------------------------- Requests ---------------------------------
0408  *
0409  * All requests/responses, which are not connector specific, must be sent over
0410  * control ring of the connector which has the index value of 0:
0411  *   /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
0412  *
0413  * All request packets have the same length (64 octets)
0414  * All request packets have common header:
0415  *         0                1                 2               3        octet
0416  * +----------------+----------------+----------------+----------------+
0417  * |               id                |    operation   |   reserved     | 4
0418  * +----------------+----------------+----------------+----------------+
0419  * |                             reserved                              | 8
0420  * +----------------+----------------+----------------+----------------+
0421  *   id - uint16_t, private guest value, echoed in response
0422  *   operation - uint8_t, operation code, XENDISPL_OP_???
0423  *
0424  * Request dbuf creation - request creation of a display buffer.
0425  *         0                1                 2               3        octet
0426  * +----------------+----------------+----------------+----------------+
0427  * |               id                |_OP_DBUF_CREATE |   reserved     | 4
0428  * +----------------+----------------+----------------+----------------+
0429  * |                             reserved                              | 8
0430  * +----------------+----------------+----------------+----------------+
0431  * |                       dbuf_cookie low 32-bit                      | 12
0432  * +----------------+----------------+----------------+----------------+
0433  * |                       dbuf_cookie high 32-bit                     | 16
0434  * +----------------+----------------+----------------+----------------+
0435  * |                               width                               | 20
0436  * +----------------+----------------+----------------+----------------+
0437  * |                               height                              | 24
0438  * +----------------+----------------+----------------+----------------+
0439  * |                                bpp                                | 28
0440  * +----------------+----------------+----------------+----------------+
0441  * |                             buffer_sz                             | 32
0442  * +----------------+----------------+----------------+----------------+
0443  * |                               flags                               | 36
0444  * +----------------+----------------+----------------+----------------+
0445  * |                           gref_directory                          | 40
0446  * +----------------+----------------+----------------+----------------+
0447  * |                             data_ofs                              | 44
0448  * +----------------+----------------+----------------+----------------+
0449  * |                             reserved                              | 48
0450  * +----------------+----------------+----------------+----------------+
0451  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0452  * +----------------+----------------+----------------+----------------+
0453  * |                             reserved                              | 64
0454  * +----------------+----------------+----------------+----------------+
0455  *
0456  * Must be sent over control ring of the connector which has the index
0457  * value of 0:
0458  *   /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
0459  * All unused bits in flags field must be set to 0.
0460  *
0461  * An attempt to create multiple display buffers with the same dbuf_cookie is
0462  * an error. dbuf_cookie can be re-used after destroying the corresponding
0463  * display buffer.
0464  *
0465  * Width and height of the display buffers can be smaller, equal or bigger
0466  * than the connector's resolution. Depth/pixel format of the individual
0467  * buffers can differ as well.
0468  *
0469  * width - uint32_t, width in pixels
0470  * height - uint32_t, height in pixels
0471  * bpp - uint32_t, bits per pixel
0472  * buffer_sz - uint32_t, buffer size to be allocated, octets
0473  * flags - uint32_t, flags of the operation
0474  *   o XENDISPL_DBUF_FLG_REQ_ALLOC - if set, then backend is requested
0475  *     to allocate the buffer with the parameters provided in this request.
0476  *     Page directory is handled as follows:
0477  *       Frontend on request:
0478  *         o allocates pages for the directory (gref_directory,
0479  *           gref_dir_next_page(s)
0480  *         o grants permissions for the pages of the directory to the backend
0481  *         o sets gref_dir_next_page fields
0482  *       Backend on response:
0483  *         o grants permissions for the pages of the buffer allocated to
0484  *           the frontend
0485  *         o fills in page directory with grant references
0486  *           (gref[] in struct xendispl_page_directory)
0487  * gref_directory - grant_ref_t, a reference to the first shared page
0488  *   describing shared buffer references. At least one page exists. If shared
0489  *   buffer size (buffer_sz) exceeds what can be addressed by this single page,
0490  *   then reference to the next page must be supplied (see gref_dir_next_page
0491  *   below)
0492  * data_ofs - uint32_t, offset of the data in the buffer, octets
0493  */
0494 
0495 #define XENDISPL_DBUF_FLG_REQ_ALLOC (1 << 0)
0496 
0497 struct xendispl_dbuf_create_req {
0498     uint64_t dbuf_cookie;
0499     uint32_t width;
0500     uint32_t height;
0501     uint32_t bpp;
0502     uint32_t buffer_sz;
0503     uint32_t flags;
0504     grant_ref_t gref_directory;
0505     uint32_t data_ofs;
0506 };
0507 
0508 /*
0509  * Shared page for XENDISPL_OP_DBUF_CREATE buffer descriptor (gref_directory in
0510  * the request) employs a list of pages, describing all pages of the shared
0511  * data buffer:
0512  *         0                1                 2               3        octet
0513  * +----------------+----------------+----------------+----------------+
0514  * |                        gref_dir_next_page                         | 4
0515  * +----------------+----------------+----------------+----------------+
0516  * |                              gref[0]                              | 8
0517  * +----------------+----------------+----------------+----------------+
0518  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0519  * +----------------+----------------+----------------+----------------+
0520  * |                              gref[i]                              | i*4+8
0521  * +----------------+----------------+----------------+----------------+
0522  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0523  * +----------------+----------------+----------------+----------------+
0524  * |                             gref[N - 1]                           | N*4+8
0525  * +----------------+----------------+----------------+----------------+
0526  *
0527  * gref_dir_next_page - grant_ref_t, reference to the next page describing
0528  *   page directory. Must be 0 if there are no more pages in the list.
0529  * gref[i] - grant_ref_t, reference to a shared page of the buffer
0530  *   allocated at XENDISPL_OP_DBUF_CREATE
0531  *
0532  * Number of grant_ref_t entries in the whole page directory is not
0533  * passed, but instead can be calculated as:
0534  *   num_grefs_total = (XENDISPL_OP_DBUF_CREATE.buffer_sz + XEN_PAGE_SIZE - 1) /
0535  *       XEN_PAGE_SIZE
0536  */
0537 
0538 struct xendispl_page_directory {
0539     grant_ref_t gref_dir_next_page;
0540     grant_ref_t gref[1]; /* Variable length */
0541 };
0542 
0543 /*
0544  * Request dbuf destruction - destroy a previously allocated display buffer:
0545  *         0                1                 2               3        octet
0546  * +----------------+----------------+----------------+----------------+
0547  * |               id                |_OP_DBUF_DESTROY|   reserved     | 4
0548  * +----------------+----------------+----------------+----------------+
0549  * |                             reserved                              | 8
0550  * +----------------+----------------+----------------+----------------+
0551  * |                       dbuf_cookie low 32-bit                      | 12
0552  * +----------------+----------------+----------------+----------------+
0553  * |                       dbuf_cookie high 32-bit                     | 16
0554  * +----------------+----------------+----------------+----------------+
0555  * |                             reserved                              | 20
0556  * +----------------+----------------+----------------+----------------+
0557  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0558  * +----------------+----------------+----------------+----------------+
0559  * |                             reserved                              | 64
0560  * +----------------+----------------+----------------+----------------+
0561  *
0562  * Must be sent over control ring of the connector which has the index
0563  * value of 0:
0564  *   /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
0565  */
0566 
0567 struct xendispl_dbuf_destroy_req {
0568     uint64_t dbuf_cookie;
0569 };
0570 
0571 /*
0572  * Request framebuffer attachment - request attachment of a framebuffer to
0573  * previously created display buffer.
0574  *         0                1                 2               3        octet
0575  * +----------------+----------------+----------------+----------------+
0576  * |               id                | _OP_FB_ATTACH  |   reserved     | 4
0577  * +----------------+----------------+----------------+----------------+
0578  * |                             reserved                              | 8
0579  * +----------------+----------------+----------------+----------------+
0580  * |                       dbuf_cookie low 32-bit                      | 12
0581  * +----------------+----------------+----------------+----------------+
0582  * |                       dbuf_cookie high 32-bit                     | 16
0583  * +----------------+----------------+----------------+----------------+
0584  * |                        fb_cookie low 32-bit                       | 20
0585  * +----------------+----------------+----------------+----------------+
0586  * |                        fb_cookie high 32-bit                      | 24
0587  * +----------------+----------------+----------------+----------------+
0588  * |                               width                               | 28
0589  * +----------------+----------------+----------------+----------------+
0590  * |                               height                              | 32
0591  * +----------------+----------------+----------------+----------------+
0592  * |                            pixel_format                           | 36
0593  * +----------------+----------------+----------------+----------------+
0594  * |                             reserved                              | 40
0595  * +----------------+----------------+----------------+----------------+
0596  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0597  * +----------------+----------------+----------------+----------------+
0598  * |                             reserved                              | 64
0599  * +----------------+----------------+----------------+----------------+
0600  *
0601  * Must be sent over control ring of the connector which has the index
0602  * value of 0:
0603  *   /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
0604  * Width and height can be smaller, equal or bigger than the connector's
0605  * resolution.
0606  *
0607  * An attempt to create multiple frame buffers with the same fb_cookie is
0608  * an error. fb_cookie can be re-used after destroying the corresponding
0609  * frame buffer.
0610  *
0611  * width - uint32_t, width in pixels
0612  * height - uint32_t, height in pixels
0613  * pixel_format - uint32_t, pixel format of the framebuffer, FOURCC code
0614  */
0615 
0616 struct xendispl_fb_attach_req {
0617     uint64_t dbuf_cookie;
0618     uint64_t fb_cookie;
0619     uint32_t width;
0620     uint32_t height;
0621     uint32_t pixel_format;
0622 };
0623 
0624 /*
0625  * Request framebuffer detach - detach a previously
0626  * attached framebuffer from the display buffer in request:
0627  *         0                1                 2               3        octet
0628  * +----------------+----------------+----------------+----------------+
0629  * |               id                |  _OP_FB_DETACH |   reserved     | 4
0630  * +----------------+----------------+----------------+----------------+
0631  * |                             reserved                              | 8
0632  * +----------------+----------------+----------------+----------------+
0633  * |                        fb_cookie low 32-bit                       | 12
0634  * +----------------+----------------+----------------+----------------+
0635  * |                        fb_cookie high 32-bit                      | 16
0636  * +----------------+----------------+----------------+----------------+
0637  * |                             reserved                              | 20
0638  * +----------------+----------------+----------------+----------------+
0639  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0640  * +----------------+----------------+----------------+----------------+
0641  * |                             reserved                              | 64
0642  * +----------------+----------------+----------------+----------------+
0643  *
0644  * Must be sent over control ring of the connector which has the index
0645  * value of 0:
0646  *   /local/domain/<dom-id>/device/vdispl/<dev-id>/0/req-ring-ref
0647  */
0648 
0649 struct xendispl_fb_detach_req {
0650     uint64_t fb_cookie;
0651 };
0652 
0653 /*
0654  * Request configuration set/reset - request to set or reset
0655  * the configuration/mode of the display:
0656  *         0                1                 2               3        octet
0657  * +----------------+----------------+----------------+----------------+
0658  * |               id                | _OP_SET_CONFIG |   reserved     | 4
0659  * +----------------+----------------+----------------+----------------+
0660  * |                             reserved                              | 8
0661  * +----------------+----------------+----------------+----------------+
0662  * |                        fb_cookie low 32-bit                       | 12
0663  * +----------------+----------------+----------------+----------------+
0664  * |                        fb_cookie high 32-bit                      | 16
0665  * +----------------+----------------+----------------+----------------+
0666  * |                                 x                                 | 20
0667  * +----------------+----------------+----------------+----------------+
0668  * |                                 y                                 | 24
0669  * +----------------+----------------+----------------+----------------+
0670  * |                               width                               | 28
0671  * +----------------+----------------+----------------+----------------+
0672  * |                               height                              | 32
0673  * +----------------+----------------+----------------+----------------+
0674  * |                                bpp                                | 40
0675  * +----------------+----------------+----------------+----------------+
0676  * |                             reserved                              | 44
0677  * +----------------+----------------+----------------+----------------+
0678  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0679  * +----------------+----------------+----------------+----------------+
0680  * |                             reserved                              | 64
0681  * +----------------+----------------+----------------+----------------+
0682  *
0683  * Pass all zeros to reset, otherwise command is treated as
0684  * configuration set.
0685  * Framebuffer's cookie defines which framebuffer/dbuf must be
0686  * displayed while enabling display (applying configuration).
0687  * x, y, width and height are bound by the connector's resolution and must not
0688  * exceed it.
0689  *
0690  * x - uint32_t, starting position in pixels by X axis
0691  * y - uint32_t, starting position in pixels by Y axis
0692  * width - uint32_t, width in pixels
0693  * height - uint32_t, height in pixels
0694  * bpp - uint32_t, bits per pixel
0695  */
0696 
0697 struct xendispl_set_config_req {
0698     uint64_t fb_cookie;
0699     uint32_t x;
0700     uint32_t y;
0701     uint32_t width;
0702     uint32_t height;
0703     uint32_t bpp;
0704 };
0705 
0706 /*
0707  * Request page flip - request to flip a page identified by the framebuffer
0708  * cookie:
0709  *         0                1                 2               3        octet
0710  * +----------------+----------------+----------------+----------------+
0711  * |               id                | _OP_PG_FLIP    |   reserved     | 4
0712  * +----------------+----------------+----------------+----------------+
0713  * |                             reserved                              | 8
0714  * +----------------+----------------+----------------+----------------+
0715  * |                        fb_cookie low 32-bit                       | 12
0716  * +----------------+----------------+----------------+----------------+
0717  * |                        fb_cookie high 32-bit                      | 16
0718  * +----------------+----------------+----------------+----------------+
0719  * |                             reserved                              | 20
0720  * +----------------+----------------+----------------+----------------+
0721  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0722  * +----------------+----------------+----------------+----------------+
0723  * |                             reserved                              | 64
0724  * +----------------+----------------+----------------+----------------+
0725  */
0726 
0727 struct xendispl_page_flip_req {
0728     uint64_t fb_cookie;
0729 };
0730 
0731 /*
0732  * Request EDID - request EDID describing current connector:
0733  *         0                1                 2               3        octet
0734  * +----------------+----------------+----------------+----------------+
0735  * |               id                | _OP_GET_EDID   |   reserved     | 4
0736  * +----------------+----------------+----------------+----------------+
0737  * |                             buffer_sz                             | 8
0738  * +----------------+----------------+----------------+----------------+
0739  * |                          gref_directory                           | 12
0740  * +----------------+----------------+----------------+----------------+
0741  * |                             reserved                              | 16
0742  * +----------------+----------------+----------------+----------------+
0743  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0744  * +----------------+----------------+----------------+----------------+
0745  * |                             reserved                              | 64
0746  * +----------------+----------------+----------------+----------------+
0747  *
0748  * Notes:
0749  *   - This command is not available in protocol version 1 and should be
0750  *     ignored.
0751  *   - This request is optional and if not supported then visible area
0752  *     is defined by the relevant XenStore's "resolution" property.
0753  *   - Shared buffer, allocated for EDID storage, must not be less then
0754  *     XENDISPL_EDID_MAX_SIZE octets.
0755  *
0756  * buffer_sz - uint32_t, buffer size to be allocated, octets
0757  * gref_directory - grant_ref_t, a reference to the first shared page
0758  *   describing EDID buffer references. See XENDISPL_OP_DBUF_CREATE for
0759  *   grant page directory structure (struct xendispl_page_directory).
0760  *
0761  * See response format for this request.
0762  */
0763 
0764 struct xendispl_get_edid_req {
0765     uint32_t buffer_sz;
0766     grant_ref_t gref_directory;
0767 };
0768 
0769 /*
0770  *---------------------------------- Responses --------------------------------
0771  *
0772  * All response packets have the same length (64 octets)
0773  *
0774  * All response packets have common header:
0775  *         0                1                 2               3        octet
0776  * +----------------+----------------+----------------+----------------+
0777  * |               id                |            reserved             | 4
0778  * +----------------+----------------+----------------+----------------+
0779  * |                              status                               | 8
0780  * +----------------+----------------+----------------+----------------+
0781  * |                             reserved                              | 12
0782  * +----------------+----------------+----------------+----------------+
0783  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0784  * +----------------+----------------+----------------+----------------+
0785  * |                             reserved                              | 64
0786  * +----------------+----------------+----------------+----------------+
0787  *
0788  * id - uint16_t, private guest value, echoed from request
0789  * status - int32_t, response status, zero on success and -XEN_EXX on failure
0790  *
0791  *
0792  * Get EDID response - response for XENDISPL_OP_GET_EDID:
0793  *         0                1                 2               3        octet
0794  * +----------------+----------------+----------------+----------------+
0795  * |               id                |    operation   |    reserved    | 4
0796  * +----------------+----------------+----------------+----------------+
0797  * |                              status                               | 8
0798  * +----------------+----------------+----------------+----------------+
0799  * |                             edid_sz                               | 12
0800  * +----------------+----------------+----------------+----------------+
0801  * |                             reserved                              | 16
0802  * +----------------+----------------+----------------+----------------+
0803  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0804  * +----------------+----------------+----------------+----------------+
0805  * |                             reserved                              | 64
0806  * +----------------+----------------+----------------+----------------+
0807  *
0808  * Notes:
0809  *   - This response is not available in protocol version 1 and should be
0810  *     ignored.
0811  *
0812  * edid_sz - uint32_t, size of the EDID, octets
0813  */
0814 
0815 struct xendispl_get_edid_resp {
0816     uint32_t edid_sz;
0817 };
0818 
0819 /*
0820  *----------------------------------- Events ----------------------------------
0821  *
0822  * Events are sent via a shared page allocated by the front and propagated by
0823  *   evt-event-channel/evt-ring-ref XenStore entries
0824  * All event packets have the same length (64 octets)
0825  * All event packets have common header:
0826  *         0                1                 2               3        octet
0827  * +----------------+----------------+----------------+----------------+
0828  * |               id                |      type      |   reserved     | 4
0829  * +----------------+----------------+----------------+----------------+
0830  * |                             reserved                              | 8
0831  * +----------------+----------------+----------------+----------------+
0832  *
0833  * id - uint16_t, event id, may be used by front
0834  * type - uint8_t, type of the event
0835  *
0836  *
0837  * Page flip complete event - event from back to front on page flip completed:
0838  *         0                1                 2               3        octet
0839  * +----------------+----------------+----------------+----------------+
0840  * |               id                |   _EVT_PG_FLIP |   reserved     | 4
0841  * +----------------+----------------+----------------+----------------+
0842  * |                             reserved                              | 8
0843  * +----------------+----------------+----------------+----------------+
0844  * |                        fb_cookie low 32-bit                       | 12
0845  * +----------------+----------------+----------------+----------------+
0846  * |                        fb_cookie high 32-bit                      | 16
0847  * +----------------+----------------+----------------+----------------+
0848  * |                             reserved                              | 20
0849  * +----------------+----------------+----------------+----------------+
0850  * |/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/|
0851  * +----------------+----------------+----------------+----------------+
0852  * |                             reserved                              | 64
0853  * +----------------+----------------+----------------+----------------+
0854  */
0855 
0856 struct xendispl_pg_flip_evt {
0857     uint64_t fb_cookie;
0858 };
0859 
0860 struct xendispl_req {
0861     uint16_t id;
0862     uint8_t operation;
0863     uint8_t reserved[5];
0864     union {
0865         struct xendispl_dbuf_create_req dbuf_create;
0866         struct xendispl_dbuf_destroy_req dbuf_destroy;
0867         struct xendispl_fb_attach_req fb_attach;
0868         struct xendispl_fb_detach_req fb_detach;
0869         struct xendispl_set_config_req set_config;
0870         struct xendispl_page_flip_req pg_flip;
0871         struct xendispl_get_edid_req get_edid;
0872         uint8_t reserved[56];
0873     } op;
0874 };
0875 
0876 struct xendispl_resp {
0877     uint16_t id;
0878     uint8_t operation;
0879     uint8_t reserved;
0880     int32_t status;
0881     union {
0882         struct xendispl_get_edid_resp get_edid;
0883         uint8_t reserved1[56];
0884     } op;
0885 };
0886 
0887 struct xendispl_evt {
0888     uint16_t id;
0889     uint8_t type;
0890     uint8_t reserved[5];
0891     union {
0892         struct xendispl_pg_flip_evt pg_flip;
0893         uint8_t reserved[56];
0894     } op;
0895 };
0896 
0897 DEFINE_RING_TYPES(xen_displif, struct xendispl_req, struct xendispl_resp);
0898 
0899 /*
0900  ******************************************************************************
0901  *                        Back to front events delivery
0902  ******************************************************************************
0903  * In order to deliver asynchronous events from back to front a shared page is
0904  * allocated by front and its granted reference propagated to back via
0905  * XenStore entries (evt-ring-ref/evt-event-channel).
0906  * This page has a common header used by both front and back to synchronize
0907  * access and control event's ring buffer, while back being a producer of the
0908  * events and front being a consumer. The rest of the page after the header
0909  * is used for event packets.
0910  *
0911  * Upon reception of an event(s) front may confirm its reception
0912  * for either each event, group of events or none.
0913  */
0914 
0915 struct xendispl_event_page {
0916     uint32_t in_cons;
0917     uint32_t in_prod;
0918     uint8_t reserved[56];
0919 };
0920 
0921 #define XENDISPL_EVENT_PAGE_SIZE XEN_PAGE_SIZE
0922 #define XENDISPL_IN_RING_OFFS (sizeof(struct xendispl_event_page))
0923 #define XENDISPL_IN_RING_SIZE (XENDISPL_EVENT_PAGE_SIZE - XENDISPL_IN_RING_OFFS)
0924 #define XENDISPL_IN_RING_LEN (XENDISPL_IN_RING_SIZE / sizeof(struct xendispl_evt))
0925 #define XENDISPL_IN_RING(page) \
0926     ((struct xendispl_evt *)((char *)(page) + XENDISPL_IN_RING_OFFS))
0927 #define XENDISPL_IN_RING_REF(page, idx) \
0928     (XENDISPL_IN_RING((page))[(idx) % XENDISPL_IN_RING_LEN])
0929 
0930 #endif /* __XEN_PUBLIC_IO_DISPLIF_H__ */