Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /* Copyright (C) 2006-2017 Oracle Corporation */
0003 
0004 #include <linux/vbox_err.h>
0005 #include "vbox_drv.h"
0006 #include "vboxvideo_guest.h"
0007 #include "vboxvideo_vbe.h"
0008 #include "hgsmi_channels.h"
0009 #include "hgsmi_ch_setup.h"
0010 
0011 /**
0012  * hgsmi_report_flags_location - Inform the host of the location of
0013  *                               the host flags in VRAM via an HGSMI cmd.
0014  * Return: 0 or negative errno value.
0015  * @ctx:        The context of the guest heap to use.
0016  * @location:   The offset chosen for the flags within guest VRAM.
0017  */
0018 int hgsmi_report_flags_location(struct gen_pool *ctx, u32 location)
0019 {
0020     struct hgsmi_buffer_location *p;
0021 
0022     p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_HGSMI,
0023                    HGSMI_CC_HOST_FLAGS_LOCATION);
0024     if (!p)
0025         return -ENOMEM;
0026 
0027     p->buf_location = location;
0028     p->buf_len = sizeof(struct hgsmi_host_flags);
0029 
0030     hgsmi_buffer_submit(ctx, p);
0031     hgsmi_buffer_free(ctx, p);
0032 
0033     return 0;
0034 }
0035 
0036 /**
0037  * hgsmi_send_caps_info - Notify the host of HGSMI-related guest capabilities
0038  *                        via an HGSMI command.
0039  * Return: 0 or negative errno value.
0040  * @ctx:        The context of the guest heap to use.
0041  * @caps:       The capabilities to report, see vbva_caps.
0042  */
0043 int hgsmi_send_caps_info(struct gen_pool *ctx, u32 caps)
0044 {
0045     struct vbva_caps *p;
0046 
0047     p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
0048     if (!p)
0049         return -ENOMEM;
0050 
0051     p->rc = VERR_NOT_IMPLEMENTED;
0052     p->caps = caps;
0053 
0054     hgsmi_buffer_submit(ctx, p);
0055 
0056     WARN_ON_ONCE(p->rc < 0);
0057 
0058     hgsmi_buffer_free(ctx, p);
0059 
0060     return 0;
0061 }
0062 
0063 int hgsmi_test_query_conf(struct gen_pool *ctx)
0064 {
0065     u32 value = 0;
0066     int ret;
0067 
0068     ret = hgsmi_query_conf(ctx, U32_MAX, &value);
0069     if (ret)
0070         return ret;
0071 
0072     return value == U32_MAX ? 0 : -EIO;
0073 }
0074 
0075 /**
0076  * hgsmi_query_conf - Query the host for an HGSMI configuration
0077  *                    parameter via an HGSMI command.
0078  * Return: 0 or negative errno value.
0079  * @ctx:        The context containing the heap used.
0080  * @index:      The index of the parameter to query.
0081  * @value_ret:  Where to store the value of the parameter on success.
0082  */
0083 int hgsmi_query_conf(struct gen_pool *ctx, u32 index, u32 *value_ret)
0084 {
0085     struct vbva_conf32 *p;
0086 
0087     p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
0088                    VBVA_QUERY_CONF32);
0089     if (!p)
0090         return -ENOMEM;
0091 
0092     p->index = index;
0093     p->value = U32_MAX;
0094 
0095     hgsmi_buffer_submit(ctx, p);
0096 
0097     *value_ret = p->value;
0098 
0099     hgsmi_buffer_free(ctx, p);
0100 
0101     return 0;
0102 }
0103 
0104 /**
0105  * hgsmi_update_pointer_shape - Pass the host a new mouse pointer shape
0106  *                              via an HGSMI command.
0107  * Return: 0 or negative errno value.
0108  * @ctx:        The context containing the heap to be used.
0109  * @flags:      Cursor flags.
0110  * @hot_x:      Horizontal position of the hot spot.
0111  * @hot_y:      Vertical position of the hot spot.
0112  * @width:      Width in pixels of the cursor.
0113  * @height:     Height in pixels of the cursor.
0114  * @pixels:     Pixel data, @see VMMDevReqMousePointer for the format.
0115  * @len:        Size in bytes of the pixel data.
0116  */
0117 int hgsmi_update_pointer_shape(struct gen_pool *ctx, u32 flags,
0118                    u32 hot_x, u32 hot_y, u32 width, u32 height,
0119                    u8 *pixels, u32 len)
0120 {
0121     struct vbva_mouse_pointer_shape *p;
0122     u32 pixel_len = 0;
0123     int rc;
0124 
0125     if (flags & VBOX_MOUSE_POINTER_SHAPE) {
0126         /*
0127          * Size of the pointer data:
0128          * sizeof (AND mask) + sizeof (XOR_MASK)
0129          */
0130         pixel_len = ((((width + 7) / 8) * height + 3) & ~3) +
0131              width * 4 * height;
0132         if (pixel_len > len)
0133             return -EINVAL;
0134 
0135         /*
0136          * If shape is supplied, then always create the pointer visible.
0137          * See comments in 'vboxUpdatePointerShape'
0138          */
0139         flags |= VBOX_MOUSE_POINTER_VISIBLE;
0140     }
0141 
0142     p = hgsmi_buffer_alloc(ctx, sizeof(*p) + pixel_len, HGSMI_CH_VBVA,
0143                    VBVA_MOUSE_POINTER_SHAPE);
0144     if (!p)
0145         return -ENOMEM;
0146 
0147     p->result = VINF_SUCCESS;
0148     p->flags = flags;
0149     p->hot_X = hot_x;
0150     p->hot_y = hot_y;
0151     p->width = width;
0152     p->height = height;
0153     if (pixel_len)
0154         memcpy(p->data, pixels, pixel_len);
0155 
0156     hgsmi_buffer_submit(ctx, p);
0157 
0158     switch (p->result) {
0159     case VINF_SUCCESS:
0160         rc = 0;
0161         break;
0162     case VERR_NO_MEMORY:
0163         rc = -ENOMEM;
0164         break;
0165     case VERR_NOT_SUPPORTED:
0166         rc = -EBUSY;
0167         break;
0168     default:
0169         rc = -EINVAL;
0170     }
0171 
0172     hgsmi_buffer_free(ctx, p);
0173 
0174     return rc;
0175 }
0176 
0177 /**
0178  * hgsmi_cursor_position - Report the guest cursor position.  The host may
0179  *                         wish to use this information to re-position its
0180  *                         own cursor (though this is currently unlikely).
0181  *                         The current host cursor position is returned.
0182  * Return: 0 or negative errno value.
0183  * @ctx:              The context containing the heap used.
0184  * @report_position:  Are we reporting a position?
0185  * @x:                Guest cursor X position.
0186  * @y:                Guest cursor Y position.
0187  * @x_host:           Host cursor X position is stored here.  Optional.
0188  * @y_host:           Host cursor Y position is stored here.  Optional.
0189  */
0190 int hgsmi_cursor_position(struct gen_pool *ctx, bool report_position,
0191               u32 x, u32 y, u32 *x_host, u32 *y_host)
0192 {
0193     struct vbva_cursor_position *p;
0194 
0195     p = hgsmi_buffer_alloc(ctx, sizeof(*p), HGSMI_CH_VBVA,
0196                    VBVA_CURSOR_POSITION);
0197     if (!p)
0198         return -ENOMEM;
0199 
0200     p->report_position = report_position;
0201     p->x = x;
0202     p->y = y;
0203 
0204     hgsmi_buffer_submit(ctx, p);
0205 
0206     *x_host = p->x;
0207     *y_host = p->y;
0208 
0209     hgsmi_buffer_free(ctx, p);
0210 
0211     return 0;
0212 }