Merge tag 'arm-dt-5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/soc/soc
[linux-2.6-microblaze.git] / drivers / gpu / drm / vboxvideo / hgsmi_base.c
1 // SPDX-License-Identifier: MIT
2 /* Copyright (C) 2006-2017 Oracle Corporation */
3
4 #include <linux/vbox_err.h>
5 #include "vbox_drv.h"
6 #include "vboxvideo_guest.h"
7 #include "vboxvideo_vbe.h"
8 #include "hgsmi_channels.h"
9 #include "hgsmi_ch_setup.h"
10
11 /**
12  * hgsmi_report_flags_location - Inform the host of the location of
13  *                               the host flags in VRAM via an HGSMI cmd.
14  * Return: 0 or negative errno value.
15  * @ctx:        The context of the guest heap to use.
16  * @location:   The offset chosen for the flags within guest VRAM.
17  */
18 int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
19 {
20         struct hgsmi_buffer_location *p;
21
22         p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
23                                HGSMI_CC_HOST_FLAGS_LOCATION);
24         if (!p)
25                 return -ENOMEM;
26
27         p->buf_location = location;
28         p->buf_len = sizeof(struct hgsmi_host_flags);
29
30         hgsmi_buffer_submit(ctx, p);
31         hgsmi_buffer_free(ctx, p);
32
33         return 0;
34 }
35
36 /**
37  * hgsmi_send_caps_info - Notify the host of HGSMI-related guest capabilities
38  *                        via an HGSMI command.
39  * Return: 0 or negative errno value.
40  * @ctx:        The context of the guest heap to use.
41  * @caps:       The capabilities to report, see vbva_caps.
42  */
43 int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
44 {
45         struct vbva_caps *p;
46
47         p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
48         if (!p)
49                 return -ENOMEM;
50
51         p->rc = VERR_NOT_IMPLEMENTED;
52         p->caps = caps;
53
54         hgsmi_buffer_submit(ctx, p);
55
56         WARN_ON_ONCE(p->rc < 0);
57
58         hgsmi_buffer_free(ctx, p);
59
60         return 0;
61 }
62
63 int hgsmi_test_query_conf(struct gen_pool *ctx)
64 {
65         u32 value = 0;
66         int ret;
67
68         ret = hgsmi_query_conf(ctx, U32_MAX, &value);
69         if (ret)
70                 return ret;
71
72         return value == U32_MAX ? 0 : -EIO;
73 }
74
75 /**
76  * hgsmi_query_conf - Query the host for an HGSMI configuration
77  *                    parameter via an HGSMI command.
78  * Return: 0 or negative errno value.
79  * @ctx:        The context containing the heap used.
80  * @index:      The index of the parameter to query.
81  * @value_ret:  Where to store the value of the parameter on success.
82  */
83 int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
84 {
85         struct vbva_conf32 *p;
86
87         p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
88                                VBVA_QUERY_CONF32);
89         if (!p)
90                 return -ENOMEM;
91
92         p->index = index;
93         p->value = U32_MAX;
94
95         hgsmi_buffer_submit(ctx, p);
96
97         *value_ret = p->value;
98
99         hgsmi_buffer_free(ctx, p);
100
101         return 0;
102 }
103
104 /**
105  * hgsmi_update_pointer_shape - Pass the host a new mouse pointer shape
106  *                              via an HGSMI command.
107  * Return: 0 or negative errno value.
108  * @ctx:        The context containing the heap to be used.
109  * @flags:      Cursor flags.
110  * @hot_x:      Horizontal position of the hot spot.
111  * @hot_y:      Vertical position of the hot spot.
112  * @width:      Width in pixels of the cursor.
113  * @height:     Height in pixels of the cursor.
114  * @pixels:     Pixel data, @see VMMDevReqMousePointer for the format.
115  * @len:        Size in bytes of the pixel data.
116  */
117 int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
118                                u32 hot_x, u32 hot_y, u32 width, u32 height,
119                                u8 *pixels, u32 len)
120 {
121         struct vbva_mouse_pointer_shape *p;
122         u32 pixel_len = 0;
123         int rc;
124
125         if (flags & VBOX_MOUSE_POINTER_SHAPE) {
126                 /*
127                  * Size of the pointer data:
128                  * sizeof (AND mask) + sizeof (XOR_MASK)
129                  */
130                 pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
131                          width * 4 * height;
132                 if (pixel_len > len)
133                         return -EINVAL;
134
135                 /*
136                  * If shape is supplied, then always create the pointer visible.
137                  * See comments in 'vboxUpdatePointerShape'
138                  */
139                 flags |= VBOX_MOUSE_POINTER_VISIBLE;
140         }
141
142         p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
143                                VBVA_MOUSE_POINTER_SHAPE);
144         if (!p)
145                 return -ENOMEM;
146
147         p->result = VINF_SUCCESS;
148         p->flags = flags;
149         p->hot_X = hot_x;
150         p->hot_y = hot_y;
151         p->width = width;
152         p->height = height;
153         if (pixel_len)
154                 memcpy(p->data, pixels, pixel_len);
155
156         hgsmi_buffer_submit(ctx, p);
157
158         switch (p->result) {
159         case VINF_SUCCESS:
160                 rc = 0;
161                 break;
162         case VERR_NO_MEMORY:
163                 rc = -ENOMEM;
164                 break;
165         case VERR_NOT_SUPPORTED:
166                 rc = -EBUSY;
167                 break;
168         default:
169                 rc = -EINVAL;
170         }
171
172         hgsmi_buffer_free(ctx, p);
173
174         return rc;
175 }
176
177 /**
178  * hgsmi_cursor_position - Report the guest cursor position.  The host may
179  *                         wish to use this information to re-position its
180  *                         own cursor (though this is currently unlikely).
181  *                         The current host cursor position is returned.
182  * Return: 0 or negative errno value.
183  * @ctx:              The context containing the heap used.
184  * @report_position:  Are we reporting a position?
185  * @x:                Guest cursor X position.
186  * @y:                Guest cursor Y position.
187  * @x_host:           Host cursor X position is stored here.  Optional.
188  * @y_host:           Host cursor Y position is stored here.  Optional.
189  */
190 int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
191                           u32 x, u32 y, u32 *x_host, u32 *y_host)
192 {
193         struct vbva_cursor_position *p;
194
195         p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
196                                VBVA_CURSOR_POSITION);
197         if (!p)
198                 return -ENOMEM;
199
200         p->report_position = report_position;
201         p->x = x;
202         p->y = y;
203
204         hgsmi_buffer_submit(ctx, p);
205
206         *x_host = p->x;
207         *y_host = p->y;
208
209         hgsmi_buffer_free(ctx, p);
210
211         return 0;
212 }