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
10 /**
11 * hgsmi_process_display_info - Set a video mode via an HGSMI request.
12 * The views must have been initialised first
13 * using @a VBoxHGSMISendViewInfo and if the mode
14 * is being set on the first display then it must
15 * be set first using registers.
16 * @ctx: The context containing the heap to use.
17 * @display: The screen number.
18 * @origin_x: The horizontal displacement relative to the first scrn.
19 * @origin_y: The vertical displacement relative to the first screen.
20 * @start_offset: The offset of the visible area of the framebuffer
21 * relative to the framebuffer start.
22 * @pitch: The offset in bytes between the starts of two adjecent
23 * scan lines in video RAM.
24 * @width: The mode width.
25 * @height: The mode height.
26 * @bpp: The colour depth of the mode.
27 * @flags: Flags.
28 */
hgsmi_process_display_info(struct gen_pool * ctx,u32 display,s32 origin_x,s32 origin_y,u32 start_offset,u32 pitch,u32 width,u32 height,u16 bpp,u16 flags)29 void hgsmi_process_display_info(struct gen_pool *ctx, u32 display,
30 s32 origin_x, s32 origin_y, u32 start_offset,
31 u32 pitch, u32 width, u32 height,
32 u16 bpp, u16 flags)
33 {
34 struct vbva_infoscreen *p;
35
36 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
37 VBVA_INFO_SCREEN);
38 if (!p)
39 return;
40
41 p->view_index = display;
42 p->origin_x = origin_x;
43 p->origin_y = origin_y;
44 p->start_offset = start_offset;
45 p->line_size = pitch;
46 p->width = width;
47 p->height = height;
48 p->bits_per_pixel = bpp;
49 p->flags = flags;
50
51 hgsmi_buffer_submit(ctx, p);
52 hgsmi_buffer_free(ctx, p);
53 }
54
55 /**
56 * hgsmi_update_input_mapping - Report the rectangle relative to which absolute
57 * pointer events should be expressed. This
58 * information remains valid until the next VBVA
59 * resize event for any screen, at which time it is
60 * reset to the bounding rectangle of all virtual
61 * screens.
62 * Return: 0 or negative errno value.
63 * @ctx: The context containing the heap to use.
64 * @origin_x: Upper left X co-ordinate relative to the first screen.
65 * @origin_y: Upper left Y co-ordinate relative to the first screen.
66 * @width: Rectangle width.
67 * @height: Rectangle height.
68 */
hgsmi_update_input_mapping(struct gen_pool * ctx,s32 origin_x,s32 origin_y,u32 width,u32 height)69 int hgsmi_update_input_mapping(struct gen_pool *ctx, s32 origin_x, s32 origin_y,
70 u32 width, u32 height)
71 {
72 struct vbva_report_input_mapping *p;
73
74 p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
75 VBVA_REPORT_INPUT_MAPPING);
76 if (!p)
77 return -ENOMEM;
78
79 p->x = origin_x;
80 p->y = origin_y;
81 p->cx = width;
82 p->cy = height;
83
84 hgsmi_buffer_submit(ctx, p);
85 hgsmi_buffer_free(ctx, p);
86
87 return 0;
88 }
89
90 /**
91 * hgsmi_get_mode_hints - Get most recent video mode hints.
92 * Return: 0 or negative errno value.
93 * @ctx: The context containing the heap to use.
94 * @screens: The number of screens to query hints for, starting at 0.
95 * @hints: Array of vbva_modehint structures for receiving the hints.
96 */
hgsmi_get_mode_hints(struct gen_pool * ctx,unsigned int screens,struct vbva_modehint * hints)97 int hgsmi_get_mode_hints(struct gen_pool *ctx, unsigned int screens,
98 struct vbva_modehint *hints)
99 {
100 struct vbva_query_mode_hints *p;
101 size_t size;
102
103 if (WARN_ON(!hints))
104 return -EINVAL;
105
106 size = screens * sizeof(struct vbva_modehint);
107 p = hgsmi_buffer_alloc(ctx, sizeof(*p) + size, HGSMI_CH_VBVA,
108 VBVA_QUERY_MODE_HINTS);
109 if (!p)
110 return -ENOMEM;
111
112 p->hints_queried_count = screens;
113 p->hint_structure_guest_size = sizeof(struct vbva_modehint);
114 p->rc = VERR_NOT_SUPPORTED;
115
116 hgsmi_buffer_submit(ctx, p);
117
118 if (p->rc < 0) {
119 hgsmi_buffer_free(ctx, p);
120 return -EIO;
121 }
122
123 memcpy(hints, ((u8 *)p) + sizeof(struct vbva_query_mode_hints), size);
124 hgsmi_buffer_free(ctx, p);
125
126 return 0;
127 }
128