2018-10-18 17:03:32 +02:00
// SPDX-License-Identifier: MIT
/* Copyright (C) 2006-2017 Oracle Corporation */
2017-07-06 16:06:01 +02:00
2018-10-18 17:03:30 +02:00
# include <linux/vbox_err.h>
2017-07-06 16:06:01 +02:00
# include "vbox_drv.h"
# include "vboxvideo_guest.h"
# include "vboxvideo_vbe.h"
# include "hgsmi_channels.h"
# include "hgsmi_ch_setup.h"
/**
* Inform the host of the location of the host flags in VRAM via an HGSMI cmd .
2018-10-18 17:03:31 +02:00
* Return : 0 or negative errno value .
* @ ctx : The context of the guest heap to use .
* @ location : The offset chosen for the flags within guest VRAM .
2017-07-06 16:06:01 +02:00
*/
int hgsmi_report_flags_location ( struct gen_pool * ctx , u32 location )
{
struct hgsmi_buffer_location * p ;
p = hgsmi_buffer_alloc ( ctx , sizeof ( * p ) , HGSMI_CH_HGSMI ,
HGSMI_CC_HOST_FLAGS_LOCATION ) ;
if ( ! p )
return - ENOMEM ;
p - > buf_location = location ;
p - > buf_len = sizeof ( struct hgsmi_host_flags ) ;
hgsmi_buffer_submit ( ctx , p ) ;
hgsmi_buffer_free ( ctx , p ) ;
return 0 ;
}
/**
* Notify the host of HGSMI - related guest capabilities via an HGSMI command .
2018-10-18 17:03:31 +02:00
* Return : 0 or negative errno value .
* @ ctx : The context of the guest heap to use .
* @ caps : The capabilities to report , see vbva_caps .
2017-07-06 16:06:01 +02:00
*/
int hgsmi_send_caps_info ( struct gen_pool * ctx , u32 caps )
{
struct vbva_caps * p ;
p = hgsmi_buffer_alloc ( ctx , sizeof ( * p ) , HGSMI_CH_VBVA , VBVA_INFO_CAPS ) ;
if ( ! p )
return - ENOMEM ;
p - > rc = VERR_NOT_IMPLEMENTED ;
p - > caps = caps ;
hgsmi_buffer_submit ( ctx , p ) ;
2018-10-18 17:03:30 +02:00
WARN_ON_ONCE ( p - > rc < 0 ) ;
2017-07-06 16:06:01 +02:00
hgsmi_buffer_free ( ctx , p ) ;
return 0 ;
}
int hgsmi_test_query_conf ( struct gen_pool * ctx )
{
u32 value = 0 ;
int ret ;
ret = hgsmi_query_conf ( ctx , U32_MAX , & value ) ;
if ( ret )
return ret ;
return value = = U32_MAX ? 0 : - EIO ;
}
/**
* Query the host for an HGSMI configuration parameter via an HGSMI command .
2018-10-18 17:03:31 +02:00
* Return : 0 or negative errno value .
* @ ctx : The context containing the heap used .
* @ index : The index of the parameter to query .
* @ value_ret : Where to store the value of the parameter on success .
2017-07-06 16:06:01 +02:00
*/
int hgsmi_query_conf ( struct gen_pool * ctx , u32 index , u32 * value_ret )
{
struct vbva_conf32 * p ;
p = hgsmi_buffer_alloc ( ctx , sizeof ( * p ) , HGSMI_CH_VBVA ,
VBVA_QUERY_CONF32 ) ;
if ( ! p )
return - ENOMEM ;
p - > index = index ;
p - > value = U32_MAX ;
hgsmi_buffer_submit ( ctx , p ) ;
* value_ret = p - > value ;
hgsmi_buffer_free ( ctx , p ) ;
return 0 ;
}
/**
* Pass the host a new mouse pointer shape via an HGSMI command .
2018-10-18 17:03:31 +02:00
* Return : 0 or negative errno value .
* @ ctx : The context containing the heap to be used .
* @ flags : Cursor flags .
* @ hot_x : Horizontal position of the hot spot .
* @ hot_y : Vertical position of the hot spot .
* @ width : Width in pixels of the cursor .
* @ height : Height in pixels of the cursor .
* @ pixels : Pixel data , @ see VMMDevReqMousePointer for the format .
* @ len : Size in bytes of the pixel data .
2017-07-06 16:06:01 +02:00
*/
int hgsmi_update_pointer_shape ( struct gen_pool * ctx , u32 flags ,
u32 hot_x , u32 hot_y , u32 width , u32 height ,
u8 * pixels , u32 len )
{
struct vbva_mouse_pointer_shape * p ;
u32 pixel_len = 0 ;
int rc ;
if ( flags & VBOX_MOUSE_POINTER_SHAPE ) {
/*
* Size of the pointer data :
* sizeof ( AND mask ) + sizeof ( XOR_MASK )
*/
pixel_len = ( ( ( ( width + 7 ) / 8 ) * height + 3 ) & ~ 3 ) +
width * 4 * height ;
if ( pixel_len > len )
return - EINVAL ;
/*
* If shape is supplied , then always create the pointer visible .
* See comments in ' vboxUpdatePointerShape '
*/
flags | = VBOX_MOUSE_POINTER_VISIBLE ;
}
p = hgsmi_buffer_alloc ( ctx , sizeof ( * p ) + pixel_len , HGSMI_CH_VBVA ,
VBVA_MOUSE_POINTER_SHAPE ) ;
if ( ! p )
return - ENOMEM ;
p - > result = VINF_SUCCESS ;
p - > flags = flags ;
p - > hot_X = hot_x ;
p - > hot_y = hot_y ;
p - > width = width ;
p - > height = height ;
if ( pixel_len )
memcpy ( p - > data , pixels , pixel_len ) ;
hgsmi_buffer_submit ( ctx , p ) ;
switch ( p - > result ) {
case VINF_SUCCESS :
rc = 0 ;
break ;
case VERR_NO_MEMORY :
rc = - ENOMEM ;
break ;
case VERR_NOT_SUPPORTED :
rc = - EBUSY ;
break ;
default :
rc = - EINVAL ;
}
hgsmi_buffer_free ( ctx , p ) ;
return rc ;
}
/**
* Report the guest cursor position . The host may wish to use this information
* to re - position its own cursor ( though this is currently unlikely ) . The
* current host cursor position is returned .
2018-10-18 17:03:31 +02:00
* Return : 0 or negative errno value .
* @ ctx : The context containing the heap used .
* @ report_position : Are we reporting a position ?
* @ x : Guest cursor X position .
* @ y : Guest cursor Y position .
* @ x_host : Host cursor X position is stored here . Optional .
* @ y_host : Host cursor Y position is stored here . Optional .
2017-07-06 16:06:01 +02:00
*/
int hgsmi_cursor_position ( struct gen_pool * ctx , bool report_position ,
u32 x , u32 y , u32 * x_host , u32 * y_host )
{
struct vbva_cursor_position * p ;
p = hgsmi_buffer_alloc ( ctx , sizeof ( * p ) , HGSMI_CH_VBVA ,
VBVA_CURSOR_POSITION ) ;
if ( ! p )
return - ENOMEM ;
p - > report_position = report_position ;
p - > x = x ;
p - > y = y ;
hgsmi_buffer_submit ( ctx , p ) ;
* x_host = p - > x ;
* y_host = p - > y ;
hgsmi_buffer_free ( ctx , p ) ;
return 0 ;
}