From: Charmaine Lee Date: Wed, 1 May 2019 21:35:54 +0000 (-0600) Subject: svga: move host logging to winsys X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9c5f407b0b44a05a52d55ec34d028a1f2a901064;p=mesa.git svga: move host logging to winsys This patch adds a host_log interface to svga_winsys and moves the host logging code to the winsys layer. Cc: mesa-stable@lists.freedesktop.org Reviewed-by: Brian Paul Reviewed-by: Neha Bhende --- diff --git a/src/gallium/drivers/svga/Makefile.sources b/src/gallium/drivers/svga/Makefile.sources index 72024cf60e1..229d2863c84 100644 --- a/src/gallium/drivers/svga/Makefile.sources +++ b/src/gallium/drivers/svga/Makefile.sources @@ -15,8 +15,6 @@ C_SOURCES := \ svga_hw_reg.h \ svga_link.c \ svga_link.h \ - svga_msg.c \ - svga_msg.h \ svga_mksstats.h \ svga_pipe_blend.c \ svga_pipe_blit.c \ diff --git a/src/gallium/drivers/svga/meson.build b/src/gallium/drivers/svga/meson.build index 7981e2991f3..4d3207a9942 100644 --- a/src/gallium/drivers/svga/meson.build +++ b/src/gallium/drivers/svga/meson.build @@ -27,7 +27,6 @@ files_svga = files( 'svga_draw_elements.c', 'svga_format.c', 'svga_link.c', - 'svga_msg.c', 'svga_pipe_blend.c', 'svga_pipe_blit.c', 'svga_pipe_clear.c', diff --git a/src/gallium/drivers/svga/svga_msg.c b/src/gallium/drivers/svga/svga_msg.c deleted file mode 100755 index 8b63132cb57..00000000000 --- a/src/gallium/drivers/svga/svga_msg.c +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "util/u_math.h" /* for MAX2/MIN2 */ -#include "util/u_debug.h" -#include "util/u_memory.h" -#include "util/u_string.h" -#include "pipe/p_defines.h" -#include "svga_msg.h" - - -#define MESSAGE_STATUS_SUCCESS 0x0001 -#define MESSAGE_STATUS_DORECV 0x0002 -#define MESSAGE_STATUS_CPT 0x0010 -#define MESSAGE_STATUS_HB 0x0080 - -#define RPCI_PROTOCOL_NUM 0x49435052 -#define GUESTMSG_FLAG_COOKIE 0x80000000 - -#define RETRIES 3 - -#define VMW_HYPERVISOR_MAGIC 0x564D5868 -#define VMW_HYPERVISOR_PORT 0x5658 -#define VMW_HYPERVISOR_HB_PORT 0x5659 - -#define VMW_PORT_CMD_MSG 30 -#define VMW_PORT_CMD_HB_MSG 0 -#define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG) -#define VMW_PORT_CMD_CLOSE_CHANNEL (MSG_TYPE_CLOSE << 16 | VMW_PORT_CMD_MSG) -#define VMW_PORT_CMD_SENDSIZE (MSG_TYPE_SENDSIZE << 16 | VMW_PORT_CMD_MSG) -#define VMW_PORT_CMD_RECVSIZE (MSG_TYPE_RECVSIZE << 16 | VMW_PORT_CMD_MSG) -#define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG) - -#define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16) - - -#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION > 502) - -/** - * Hypervisor-specific bi-directional communication channel. Should never - * execute on bare metal hardware. The caller must make sure to check for - * supported hypervisor before using these macros. - * - * The last two parameters are both input and output and must be initialized. - * - * @cmd: [IN] Message Cmd - * @in_bx: [IN] Message Len, through BX - * @in_si: [IN] Input argument through SI, set to 0 if not used - * @in_di: [IN] Input argument through DI, set ot 0 if not used - * @port_num: [IN] port number + [channel id] - * @magic: [IN] hypervisor magic value - * @ax: [OUT] value of AX register - * @bx: [OUT] e.g. status from an HB message status command - * @cx: [OUT] e.g. status from a non-HB message status command - * @dx: [OUT] e.g. channel id - * @si: [OUT] - * @di: [OUT] - */ -#define VMW_PORT(cmd, in_bx, in_si, in_di, \ - port_num, magic, \ - ax, bx, cx, dx, si, di) \ -({ \ - __asm__ volatile ("inl %%dx, %%eax;" : \ - "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) : \ - "a"(magic), \ - "b"(in_bx), \ - "c"(cmd), \ - "d"(port_num), \ - "S"(in_si), \ - "D"(in_di) : \ - "memory"); \ -}) - - - -/** - * Hypervisor-specific bi-directional communication channel. Should never - * execute on bare metal hardware. The caller must make sure to check for - * supported hypervisor before using these macros. - * - * @cmd: [IN] Message Cmd - * @in_cx: [IN] Message Len, through CX - * @in_si: [IN] Input argument through SI, set to 0 if not used - * @in_di: [IN] Input argument through DI, set to 0 if not used - * @port_num: [IN] port number + [channel id] - * @magic: [IN] hypervisor magic value - * @bp: [IN] - * @ax: [OUT] value of AX register - * @bx: [OUT] e.g. status from an HB message status command - * @cx: [OUT] e.g. status from a non-HB message status command - * @dx: [OUT] e.g. channel id - * @si: [OUT] - * @di: [OUT] - */ -#if defined(PIPE_ARCH_X86_64) - -typedef uint64_t VMW_REG; - -#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ -({ \ - __asm__ volatile ("push %%rbp;" \ - "movq %12, %%rbp;" \ - "rep outsb;" \ - "pop %%rbp;" : \ - "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) : \ - "a"(magic), \ - "b"(cmd), \ - "c"(in_cx), \ - "d"(port_num), \ - "S"(in_si), \ - "D"(in_di), \ - "r"(bp) : \ - "memory", "cc"); \ -}) - -#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ -({ \ - __asm__ volatile ("push %%rbp;" \ - "movq %12, %%rbp;" \ - "rep insb;" \ - "pop %%rbp" : \ - "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) : \ - "a"(magic), \ - "b"(cmd), \ - "c"(in_cx), \ - "d"(port_num), \ - "S"(in_si), \ - "D"(in_di), \ - "r"(bp) : \ - "memory", "cc"); \ -}) - -#else - -typedef uint32_t VMW_REG; - -/* In the 32-bit version of this macro, we use "m" because there is no - * more register left for bp - */ -#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ -({ \ - __asm__ volatile ("push %%ebp;" \ - "mov %12, %%ebp;" \ - "rep outsb;" \ - "pop %%ebp;" : \ - "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) : \ - "a"(magic), \ - "b"(cmd), \ - "c"(in_cx), \ - "d"(port_num), \ - "S"(in_si), \ - "D"(in_di), \ - "m"(bp) : \ - "memory", "cc"); \ -}) - - -#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ -({ \ - __asm__ volatile ("push %%ebp;" \ - "mov %12, %%ebp;" \ - "rep insb;" \ - "pop %%ebp" : \ - "=a"(ax), \ - "=b"(bx), \ - "=c"(cx), \ - "=d"(dx), \ - "=S"(si), \ - "=D"(di) : \ - "a"(magic), \ - "b"(cmd), \ - "c"(in_cx), \ - "d"(port_num), \ - "S"(in_si), \ - "D"(in_di), \ - "m"(bp) : \ - "memory", "cc"); \ -}) - -#endif - -#else - -#define MSG_NOT_IMPLEMENTED 1 - -/* not implemented */ - -typedef uint32_t VMW_REG; - - -#define VMW_PORT(cmd, in_bx, in_si, in_di, \ - port_num, magic, \ - ax, bx, cx, dx, si, di) \ - (void) in_bx; \ - (void) ax; (void) bx; (void) cx; \ - (void) dx; (void) si; (void) di; - -#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ - (void) in_cx; (void) bp; \ - (void) ax; (void) bx; (void) cx; \ - (void) dx; (void) si; (void) di; - - -#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ - port_num, magic, bp, \ - ax, bx, cx, dx, si, di) \ - (void) bp; \ - (void) ax; (void) bx; (void) cx; \ - (void) dx; (void) si; (void) di; - -#endif /* #if PIPE_CC_GCC */ - - -enum rpc_msg_type { - MSG_TYPE_OPEN, - MSG_TYPE_SENDSIZE, - MSG_TYPE_SENDPAYLOAD, - MSG_TYPE_RECVSIZE, - MSG_TYPE_RECVPAYLOAD, - MSG_TYPE_RECVSTATUS, - MSG_TYPE_CLOSE, -}; - -struct rpc_channel { - uint16_t channel_id; - uint32_t cookie_high; - uint32_t cookie_low; -}; - - - -/** - * svga_open_channel - * - * @channel: RPC channel - * @protocol: - * - * Returns: PIPE_OK on success, PIPE_ERROR otherwise - */ -static enum pipe_error -svga_open_channel(struct rpc_channel *channel, unsigned protocol) -{ - VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0; - - VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL, - (protocol | GUESTMSG_FLAG_COOKIE), si, di, - VMW_HYPERVISOR_PORT, - VMW_HYPERVISOR_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0) - return PIPE_ERROR; - - channel->channel_id = HIGH_WORD(dx); - channel->cookie_high = si; - channel->cookie_low = di; - - return PIPE_OK; -} - - - -/** - * svga_close_channel - * - * @channel: RPC channel - * - * Returns: PIPE_OK on success, PIPE_ERROR otherwises - */ -static enum pipe_error -svga_close_channel(struct rpc_channel *channel) -{ - VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si, di; - - /* Set up additional parameters */ - si = channel->cookie_high; - di = channel->cookie_low; - - VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL, - 0, si, di, - (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)), - VMW_HYPERVISOR_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0) - return PIPE_ERROR; - - return PIPE_OK; -} - - - -/** - * svga_send_msg: Sends a message to the host - * - * @channel: RPC channel - * @logmsg: NULL terminated string - * - * Returns: PIPE_OK on success - */ -static enum pipe_error -svga_send_msg(struct rpc_channel *channel, const char *msg) -{ - VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si, di, bp; - size_t msg_len = strlen(msg); - int retries = 0; - - - while (retries < RETRIES) { - retries++; - - /* Set up additional parameters */ - si = channel->cookie_high; - di = channel->cookie_low; - - VMW_PORT(VMW_PORT_CMD_SENDSIZE, - msg_len, si, di, - VMW_HYPERVISOR_PORT | (channel->channel_id << 16), - VMW_HYPERVISOR_MAGIC, - ax, bx, cx, dx, si, di); - - if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0 || - (HIGH_WORD(cx) & MESSAGE_STATUS_HB) == 0) { - /* Expected success + high-bandwidth. Give up. */ - return PIPE_ERROR; - } - - /* Send msg */ - si = (uintptr_t) msg; - di = channel->cookie_low; - bp = channel->cookie_high; - - VMW_PORT_HB_OUT( - (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, - msg_len, si, di, - VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), - VMW_HYPERVISOR_MAGIC, bp, - ax, bx, cx, dx, si, di); - - if ((HIGH_WORD(bx) & MESSAGE_STATUS_SUCCESS) != 0) { - return PIPE_OK; - } else if ((HIGH_WORD(bx) & MESSAGE_STATUS_CPT) != 0) { - /* A checkpoint occurred. Retry. */ - continue; - } else { - break; - } - } - - return PIPE_ERROR; -} - - - -/** - * svga_host_log: Sends a log message to the host - * - * @log: NULL terminated string - * - * Returns: PIPE_OK on success - */ -enum pipe_error -svga_host_log(const char *log) -{ - struct rpc_channel channel; - char *msg; - int msg_len; - enum pipe_error ret = PIPE_OK; - -#ifdef MSG_NOT_IMPLEMENTED - return ret; -#endif - - if (!log) - return ret; - - msg_len = strlen(log) + strlen("log ") + 1; - msg = CALLOC(1, msg_len); - if (msg == NULL) { - debug_printf("Cannot allocate memory for log message\n"); - return PIPE_ERROR_OUT_OF_MEMORY; - } - - util_sprintf(msg, "log %s", log); - - if (svga_open_channel(&channel, RPCI_PROTOCOL_NUM) || - svga_send_msg(&channel, msg) || - svga_close_channel(&channel)) { - debug_printf("Failed to send log\n"); - - ret = PIPE_ERROR; - } - - FREE(msg); - - return ret; -} - diff --git a/src/gallium/drivers/svga/svga_msg.h b/src/gallium/drivers/svga/svga_msg.h deleted file mode 100644 index 9132ba7e240..00000000000 --- a/src/gallium/drivers/svga/svga_msg.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Based on code from vmware.c and vmmouse.c. - * Author: - * Sinclair Yeh - */ -#ifndef _SVGA_MSG_H -#define _SVGA_MSG_H - -/** - * svga_host_log: Sends a log message to the host - * - * @log: NULL terminated string - * - * Returns: PIPE_OK on success - */ -enum pipe_error svga_host_log(const char *log); - -#endif - diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 6cb5a14f5b0..664b9bf615d 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -37,7 +37,6 @@ #include "svga_public.h" #include "svga_context.h" #include "svga_format.h" -#include "svga_msg.h" #include "svga_screen.h" #include "svga_tgsi.h" #include "svga_resource_texture.h" @@ -891,17 +890,18 @@ svga_get_driver_query_info(struct pipe_screen *screen, static void init_logging(struct pipe_screen *screen) { + struct svga_screen *svgascreen = svga_screen(screen); static const char *log_prefix = "Mesa: "; char host_log[1000]; /* Log Version to Host */ util_snprintf(host_log, sizeof(host_log) - strlen(log_prefix), - "%s%s", log_prefix, svga_get_name(screen)); - svga_host_log(host_log); + "%s%s\n", log_prefix, svga_get_name(screen)); + svgascreen->sws->host_log(svgascreen->sws, host_log); util_snprintf(host_log, sizeof(host_log) - strlen(log_prefix), "%s" PACKAGE_VERSION MESA_GIT_SHA1, log_prefix); - svga_host_log(host_log); + svgascreen->sws->host_log(svgascreen->sws, host_log); /* If the SVGA_EXTRA_LOGGING env var is set, log the process's command * line (program name and arguments). @@ -910,8 +910,8 @@ init_logging(struct pipe_screen *screen) char cmdline[1000]; if (os_get_command_line(cmdline, sizeof(cmdline))) { util_snprintf(host_log, sizeof(host_log) - strlen(log_prefix), - "%s%s", log_prefix, cmdline); - svga_host_log(host_log); + "%s%s\n", log_prefix, cmdline); + svgascreen->sws->host_log(svgascreen->sws, host_log); } } } diff --git a/src/gallium/drivers/svga/svga_winsys.h b/src/gallium/drivers/svga/svga_winsys.h index a067a7ba09d..14782e19a7d 100644 --- a/src/gallium/drivers/svga/svga_winsys.h +++ b/src/gallium/drivers/svga/svga_winsys.h @@ -753,6 +753,11 @@ struct svga_winsys_screen void (*stats_time_pop)(); + /** + * Send a host log message + */ + void + (*host_log)(struct svga_winsys_screen *sws, const char *message); /** Have VGPU v10 hardware? */ boolean have_vgpu10; diff --git a/src/gallium/winsys/svga/drm/Makefile.sources b/src/gallium/winsys/svga/drm/Makefile.sources index f82b0097b5b..191f0b88b4a 100644 --- a/src/gallium/winsys/svga/drm/Makefile.sources +++ b/src/gallium/winsys/svga/drm/Makefile.sources @@ -8,6 +8,8 @@ C_SOURCES := \ vmw_fence.c \ vmw_fence.h \ vmwgfx_drm.h \ + vmw_msg.c \ + vmw_msg.h \ vmw_screen.c \ vmw_screen_dri.c \ vmw_screen.h \ diff --git a/src/gallium/winsys/svga/drm/meson.build b/src/gallium/winsys/svga/drm/meson.build index 24f67aca9ec..55266ce1623 100644 --- a/src/gallium/winsys/svga/drm/meson.build +++ b/src/gallium/winsys/svga/drm/meson.build @@ -23,6 +23,7 @@ files_svgadrm = files( 'vmw_buffer.c', 'vmw_context.c', 'vmw_fence.c', + 'vmw_msg.c', 'vmw_screen.c', 'vmw_screen_dri.c', 'vmw_screen_ioctl.c', diff --git a/src/gallium/winsys/svga/drm/vmw_msg.c b/src/gallium/winsys/svga/drm/vmw_msg.c new file mode 100644 index 00000000000..8cce2241f36 --- /dev/null +++ b/src/gallium/winsys/svga/drm/vmw_msg.c @@ -0,0 +1,448 @@ +/* + * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "util/u_math.h" /* for MAX2/MIN2 */ +#include "util/u_debug.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "pipe/p_defines.h" +#include "svga_winsys.h" +#include "vmw_msg.h" + + +#define MESSAGE_STATUS_SUCCESS 0x0001 +#define MESSAGE_STATUS_DORECV 0x0002 +#define MESSAGE_STATUS_CPT 0x0010 +#define MESSAGE_STATUS_HB 0x0080 + +#define RPCI_PROTOCOL_NUM 0x49435052 +#define GUESTMSG_FLAG_COOKIE 0x80000000 + +#define RETRIES 3 + +#define VMW_HYPERVISOR_MAGIC 0x564D5868 +#define VMW_HYPERVISOR_PORT 0x5658 +#define VMW_HYPERVISOR_HB_PORT 0x5659 + +#define VMW_PORT_CMD_MSG 30 +#define VMW_PORT_CMD_HB_MSG 0 +#define VMW_PORT_CMD_OPEN_CHANNEL (MSG_TYPE_OPEN << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_CLOSE_CHANNEL (MSG_TYPE_CLOSE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_SENDSIZE (MSG_TYPE_SENDSIZE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_RECVSIZE (MSG_TYPE_RECVSIZE << 16 | VMW_PORT_CMD_MSG) +#define VMW_PORT_CMD_RECVSTATUS (MSG_TYPE_RECVSTATUS << 16 | VMW_PORT_CMD_MSG) + +#define HIGH_WORD(X) ((X & 0xFFFF0000) >> 16) + + +#if defined(PIPE_CC_GCC) && (PIPE_CC_GCC_VERSION > 502) + +/** + * Hypervisor-specific bi-directional communication channel. Should never + * execute on bare metal hardware. The caller must make sure to check for + * supported hypervisor before using these macros. + * + * The last two parameters are both input and output and must be initialized. + * + * @cmd: [IN] Message Cmd + * @in_bx: [IN] Message Len, through BX + * @in_si: [IN] Input argument through SI, set to 0 if not used + * @in_di: [IN] Input argument through DI, set ot 0 if not used + * @port_num: [IN] port number + [channel id] + * @magic: [IN] hypervisor magic value + * @ax: [OUT] value of AX register + * @bx: [OUT] e.g. status from an HB message status command + * @cx: [OUT] e.g. status from a non-HB message status command + * @dx: [OUT] e.g. channel id + * @si: [OUT] + * @di: [OUT] + */ +#define VMW_PORT(cmd, in_bx, in_si, in_di, \ + port_num, magic, \ + ax, bx, cx, dx, si, di) \ +({ \ + __asm__ volatile ("inl %%dx, %%eax;" : \ + "=a"(ax), \ + "=b"(bx), \ + "=c"(cx), \ + "=d"(dx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(in_bx), \ + "c"(cmd), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di) : \ + "memory"); \ +}) + + + +/** + * Hypervisor-specific bi-directional communication channel. Should never + * execute on bare metal hardware. The caller must make sure to check for + * supported hypervisor before using these macros. + * + * @cmd: [IN] Message Cmd + * @in_cx: [IN] Message Len, through CX + * @in_si: [IN] Input argument through SI, set to 0 if not used + * @in_di: [IN] Input argument through DI, set to 0 if not used + * @port_num: [IN] port number + [channel id] + * @magic: [IN] hypervisor magic value + * @bp: [IN] + * @ax: [OUT] value of AX register + * @bx: [OUT] e.g. status from an HB message status command + * @cx: [OUT] e.g. status from a non-HB message status command + * @dx: [OUT] e.g. channel id + * @si: [OUT] + * @di: [OUT] + */ +#if defined(PIPE_ARCH_X86_64) + +typedef uint64_t VMW_REG; + +#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ +({ \ + __asm__ volatile ("push %%rbp;" \ + "movq %12, %%rbp;" \ + "rep outsb;" \ + "pop %%rbp;" : \ + "=a"(ax), \ + "=b"(bx), \ + "=c"(cx), \ + "=d"(dx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_cx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + +#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ +({ \ + __asm__ volatile ("push %%rbp;" \ + "movq %12, %%rbp;" \ + "rep insb;" \ + "pop %%rbp" : \ + "=a"(ax), \ + "=b"(bx), \ + "=c"(cx), \ + "=d"(dx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_cx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "r"(bp) : \ + "memory", "cc"); \ +}) + +#else + +typedef uint32_t VMW_REG; + +/* In the 32-bit version of this macro, we use "m" because there is no + * more register left for bp + */ +#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ +({ \ + __asm__ volatile ("push %%ebp;" \ + "mov %12, %%ebp;" \ + "rep outsb;" \ + "pop %%ebp;" : \ + "=a"(ax), \ + "=b"(bx), \ + "=c"(cx), \ + "=d"(dx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_cx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "m"(bp) : \ + "memory", "cc"); \ +}) + + +#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ +({ \ + __asm__ volatile ("push %%ebp;" \ + "mov %12, %%ebp;" \ + "rep insb;" \ + "pop %%ebp" : \ + "=a"(ax), \ + "=b"(bx), \ + "=c"(cx), \ + "=d"(dx), \ + "=S"(si), \ + "=D"(di) : \ + "a"(magic), \ + "b"(cmd), \ + "c"(in_cx), \ + "d"(port_num), \ + "S"(in_si), \ + "D"(in_di), \ + "m"(bp) : \ + "memory", "cc"); \ +}) + +#endif + +#else + +#define MSG_NOT_IMPLEMENTED 1 + +/* not implemented */ + +typedef uint32_t VMW_REG; + + +#define VMW_PORT(cmd, in_bx, in_si, in_di, \ + port_num, magic, \ + ax, bx, cx, dx, si, di) \ + (void) in_bx; \ + (void) ax; (void) bx; (void) cx; \ + (void) dx; (void) si; (void) di; + +#define VMW_PORT_HB_OUT(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ + (void) in_cx; (void) bp; \ + (void) ax; (void) bx; (void) cx; \ + (void) dx; (void) si; (void) di; + + +#define VMW_PORT_HB_IN(cmd, in_cx, in_si, in_di, \ + port_num, magic, bp, \ + ax, bx, cx, dx, si, di) \ + (void) bp; \ + (void) ax; (void) bx; (void) cx; \ + (void) dx; (void) si; (void) di; + +#endif /* #if PIPE_CC_GCC */ + + +enum rpc_msg_type { + MSG_TYPE_OPEN, + MSG_TYPE_SENDSIZE, + MSG_TYPE_SENDPAYLOAD, + MSG_TYPE_RECVSIZE, + MSG_TYPE_RECVPAYLOAD, + MSG_TYPE_RECVSTATUS, + MSG_TYPE_CLOSE, +}; + +struct rpc_channel { + uint16_t channel_id; + uint32_t cookie_high; + uint32_t cookie_low; +}; + + + +/** + * vmw_open_channel + * + * @channel: RPC channel + * @protocol: + * + * Returns: PIPE_OK on success, PIPE_ERROR otherwise + */ +static enum pipe_error +vmw_open_channel(struct rpc_channel *channel, unsigned protocol) +{ + VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0; + + VMW_PORT(VMW_PORT_CMD_OPEN_CHANNEL, + (protocol | GUESTMSG_FLAG_COOKIE), si, di, + VMW_HYPERVISOR_PORT, + VMW_HYPERVISOR_MAGIC, + ax, bx, cx, dx, si, di); + + if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0) + return PIPE_ERROR; + + channel->channel_id = HIGH_WORD(dx); + channel->cookie_high = si; + channel->cookie_low = di; + + return PIPE_OK; +} + + + +/** + * svga_close_channel + * + * @channel: RPC channel + * + * Returns: PIPE_OK on success, PIPE_ERROR otherwises + */ +static enum pipe_error +vmw_close_channel(struct rpc_channel *channel) +{ + VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si, di; + + /* Set up additional parameters */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_CLOSE_CHANNEL, + 0, si, di, + (VMW_HYPERVISOR_PORT | (channel->channel_id << 16)), + VMW_HYPERVISOR_MAGIC, + ax, bx, cx, dx, si, di); + + if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0) + return PIPE_ERROR; + + return PIPE_OK; +} + + + +/** + * vmw_send_msg: Sends a message to the host + * + * @channel: RPC channel + * @logmsg: NULL terminated string + * + * Returns: PIPE_OK on success + */ +static enum pipe_error +vmw_send_msg(struct rpc_channel *channel, const char *msg) +{ + VMW_REG ax = 0, bx = 0, cx = 0, dx = 0, si, di, bp; + size_t msg_len = strlen(msg); + int retries = 0; + + + while (retries < RETRIES) { + retries++; + + /* Set up additional parameters */ + si = channel->cookie_high; + di = channel->cookie_low; + + VMW_PORT(VMW_PORT_CMD_SENDSIZE, + msg_len, si, di, + VMW_HYPERVISOR_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, + ax, bx, cx, dx, si, di); + + if ((HIGH_WORD(cx) & MESSAGE_STATUS_SUCCESS) == 0 || + (HIGH_WORD(cx) & MESSAGE_STATUS_HB) == 0) { + /* Expected success + high-bandwidth. Give up. */ + return PIPE_ERROR; + } + + /* Send msg */ + si = (uintptr_t) msg; + di = channel->cookie_low; + bp = channel->cookie_high; + + VMW_PORT_HB_OUT( + (MESSAGE_STATUS_SUCCESS << 16) | VMW_PORT_CMD_HB_MSG, + msg_len, si, di, + VMW_HYPERVISOR_HB_PORT | (channel->channel_id << 16), + VMW_HYPERVISOR_MAGIC, bp, + ax, bx, cx, dx, si, di); + + if ((HIGH_WORD(bx) & MESSAGE_STATUS_SUCCESS) != 0) { + return PIPE_OK; + } else if ((HIGH_WORD(bx) & MESSAGE_STATUS_CPT) != 0) { + /* A checkpoint occurred. Retry. */ + continue; + } else { + break; + } + } + + return PIPE_ERROR; +} + + + +/** + * vmw_svga_winsys_host_log: Sends a log message to the host + * + * @log: NULL terminated string + * + */ +void +vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, const char *log) +{ + struct rpc_channel channel; + char *msg; + int msg_len; + +#ifdef MSG_NOT_IMPLEMENTED + return; +#endif + + if (!log) + return; + + msg_len = strlen(log) + strlen("log ") + 1; + msg = CALLOC(1, msg_len); + if (msg == NULL) { + debug_printf("Cannot allocate memory for log message\n"); + return; + } + + util_sprintf(msg, "log %s", log); + + if (vmw_open_channel(&channel, RPCI_PROTOCOL_NUM) || + vmw_send_msg(&channel, msg) || + vmw_close_channel(&channel)) { + debug_printf("Failed to send log\n"); + } + + FREE(msg); + + return; +} + diff --git a/src/gallium/winsys/svga/drm/vmw_msg.h b/src/gallium/winsys/svga/drm/vmw_msg.h new file mode 100644 index 00000000000..57057f23638 --- /dev/null +++ b/src/gallium/winsys/svga/drm/vmw_msg.h @@ -0,0 +1,41 @@ +/* + * Copyright © 2016 VMware, Inc., Palo Alto, CA., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Based on code from vmware.c and vmmouse.c. + * Author: + * Sinclair Yeh + */ +#ifndef _VMW_MSG_H +#define _VMW_MSG_H + +/** + * vmw_host_log: Sends a log message to the host + * + * @log: NULL terminated string + * + */ +void vmw_svga_winsys_host_log(struct svga_winsys_screen *sws, const char *log); + +#endif + diff --git a/src/gallium/winsys/svga/drm/vmw_screen_svga.c b/src/gallium/winsys/svga/drm/vmw_screen_svga.c index a6990414e20..cd3f21f6033 100644 --- a/src/gallium/winsys/svga/drm/vmw_screen_svga.c +++ b/src/gallium/winsys/svga/drm/vmw_screen_svga.c @@ -48,6 +48,7 @@ #include "vmw_surface.h" #include "vmw_buffer.h" #include "vmw_fence.h" +#include "vmw_msg.h" #include "vmw_shader.h" #include "vmw_query.h" #include "svga3d_surfacedefs.h" @@ -509,6 +510,8 @@ vmw_winsys_screen_init_svga(struct vmw_winsys_screen *vws) vws->base.stats_time_push = vmw_svga_winsys_stats_time_push; vws->base.stats_time_pop = vmw_svga_winsys_stats_time_pop; + vws->base.host_log = vmw_svga_winsys_host_log; + return TRUE; }