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