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