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