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