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