From aa69cb8e873e52802ea7ff8be9b6722bf45cc7a3 Mon Sep 17 00:00:00 2001 From: Jinyoung Park Date: Thu, 27 Jul 2017 21:05:51 +0900 Subject: virt: tegra: Add tegra_hv_pm_ctl driver Added Nvidia Tegra hypervisor PM control to handle power state transition commands over IVC channel. Supported system shutdown/reboot initiation via sysfs. Updated hyp_guest_reset hvc call interface. STR-293 STR-294 STR-364 Jira VFND-4029 Jira HYP-77 Change-Id: I60274121de27495e5ae11ba34b02b65350496a9b Signed-off-by: Jinyoung Park Reviewed-on: https://git-master.nvidia.com/r/1528042 GVS: Gerrit_Virtual_Submit Reviewed-by: Abhijit . Tested-by: Sang-Hun Lee Reviewed-by: Sumeet Gupta --- include/soc/tegra/virt/syscalls.h | 23 +++++-- include/soc/tegra/virt/tegra_hv_pm_ctl.h | 22 +++++++ include/soc/tegra/virt/tegra_hv_sysmgr.h | 106 +++++++++++++++++++++++++++++++ 3 files changed, 146 insertions(+), 5 deletions(-) create mode 100644 include/soc/tegra/virt/tegra_hv_pm_ctl.h create mode 100644 include/soc/tegra/virt/tegra_hv_sysmgr.h (limited to 'include/soc/tegra/virt') diff --git a/include/soc/tegra/virt/syscalls.h b/include/soc/tegra/virt/syscalls.h index 55805f203..ed92cb239 100644 --- a/include/soc/tegra/virt/syscalls.h +++ b/include/soc/tegra/virt/syscalls.h @@ -34,6 +34,8 @@ #ifndef __VMM_SYSCALLS_H__ #define __VMM_SYSCALLS_H__ +#include + #define HVC_NR_READ_STAT 1 #define HVC_NR_READ_IVC 2 #define HVC_NR_READ_GID 3 @@ -293,14 +295,25 @@ static inline int hyp_read_hyp_info(uint64_t *hyp_info_page_pa) return (int)r0; } -static inline int hyp_guest_reset(unsigned int vmid) +static inline int hyp_guest_reset(unsigned int id, + struct hyp_sys_state_info *out) { - register uint64_t r0 asm("x0") = vmid; + register uint64_t r0 asm("x0") = id; + register uint64_t r1 asm("x1"); + register uint64_t r2 asm("x2"); + register uint64_t r3 asm("x3"); - asm volatile("hvc %1" - : "+r"(r0) + asm volatile("hvc %4" + : "+r"(r0), "=r"(r1), + "=r"(r2), "=r"(r3) : "i"(HVC_NR_GUEST_RESET) - : "x1", "x2", "x3", _X4_X17); + : _X4_X17); + + if (out != 0) { + out->sys_transition_mask = (uint32_t)r1; + out->vm_shutdown_mask = (uint32_t)r2; + out->vm_reboot_mask = (uint32_t)r3; + } return (int)r0; } diff --git a/include/soc/tegra/virt/tegra_hv_pm_ctl.h b/include/soc/tegra/virt/tegra_hv_pm_ctl.h new file mode 100644 index 000000000..2ae163628 --- /dev/null +++ b/include/soc/tegra/virt/tegra_hv_pm_ctl.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _TEGRA_HV_PM_CTL_H +#define _TEGRA_HV_PM_CTL_H + +extern int (*tegra_hv_pm_ctl_prepare_shutdown)(void); + +int tegra_hv_pm_ctl_trigger_sys_shutdown(void); +int tegra_hv_pm_ctl_trigger_sys_reboot(void); + +#endif /* _TEGRA_HV_PM_CTL_H */ diff --git a/include/soc/tegra/virt/tegra_hv_sysmgr.h b/include/soc/tegra/virt/tegra_hv_sysmgr.h new file mode 100644 index 000000000..f446c1a36 --- /dev/null +++ b/include/soc/tegra/virt/tegra_hv_sysmgr.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _TEGRA_HV_SYSMGR_H +#define _TEGRA_HV_SYSMGR_H + +#include + +#define SYSMGR_IVCMSG_SIZE_MAX 64 + +enum hv_sysmgr_msg_type { + HV_SYSMGR_MSG_TYPE_GUEST_EVENT = 1, + HV_SYSMGR_MSG_TYPE_VM_PM_CTL_CMD = 2, + HV_SYSMGR_MSG_TYPE_INVALID +}; + +enum hv_sysmgr_cmd_id { + HV_SYSMGR_CMD_NORMAL_SHUTDOWN = 0x0, + HV_SYSMGR_CMD_NORMAL_REBOOT = 0x1, + HV_SYSMGR_CMD_NORMAL_SUSPEND = 0x2, + HV_SYSMGR_CMD_NORMAL_RESUME = 0x3, + HV_SYSMGR_CMD_INVALID = 0xFFFFFFFF, +}; + +enum hv_sysmgr_resp_id { + HV_SYSMGR_RESP_ACCEPTED = 0x0, + HV_SYSMGR_RESP_UNKNOWN_COMMAND = 0xF, +}; + +/* This struct comes as payload of hv_pm_ctl_message */ +struct hv_sysmgr_command { + uint32_t cmd_id; + uint32_t resp_id; +} __packed; + +struct hv_sysmgr_message { + /* msg class */ + uint32_t msg_type; + /* id of open socket */ + uint32_t socket_id; + /* client data area. Payload */ + uint8_t client_data[SYSMGR_IVCMSG_SIZE_MAX]; +} __packed; + + +/* + * QUERY_SYSTEM_STATE COMMAND DATA LAYOUT + */ +struct hyp_sys_state_info { + /* Indicates System State Transition */ + uint32_t sys_transition_mask; + + /* Indicates which VM shutdown request is pending */ + uint32_t vm_shutdown_mask; + + /* Indicates which VM reboot request is pending */ + uint32_t vm_reboot_mask; +}; + +/* + * Power management calls ID's used by SYSMGR to manage LOCAL/GLOBAL EVENTS + */ +enum system_function_id { + INVALID_FUNC, + /* + * This is used to get reboot/shutdown masks per VM from hypervisor. + * Hypervisor updates state fields on a PSCI event from the VM. + */ + QUERY_SYSTEM_STATE, + GUEST_SHUTDOWN_INIT, + GUEST_SHUTDOWN_COMPLETE, + GUEST_REBOOT_INIT, + GUEST_REBOOT_CONTINUE, + GUEST_REBOOT_COMPLETE, + SYSTEM_SHUTDOWN_INIT, + SYSTEM_SHUTDOWN_COMPLETE, + SYSTEM_REBOOT_INIT, + SYSTEM_REBOOT_COMPLETE, + MAX_FUNC_ID, +}; + +#define CREATE_CMD(func_id, vmid) ((func_id << 24U) | vmid) + +#define QUERY_CMD CREATE_CMD(QUERY_SYSTEM_STATE, 0) +#define GUEST_SHUTDOWN_INIT_CMD(vmid) CREATE_CMD(GUEST_SHUTDOWN_INIT, vmid) +#define GUEST_SHUTDOWN_COMPLETE_CMD(vmid) \ + CREATE_CMD(GUEST_SHUTDOWN_COMPLETE, vmid) +#define GUEST_REBOOT_INIT_CMD(vmid) CREATE_CMD(GUEST_REBOOT_INIT, vmid) +#define GUEST_REBOOT_CONTINUE_CMD(vmid) CREATE_CMD(GUEST_REBOOT_CONTINUE, vmid) +#define GUEST_REBOOT_COMPLETE_CMD(vmid) CREATE_CMD(GUEST_REBOOT_COMPLETE, vmid) +#define SYS_SHUTDOWN_INIT_CMD CREATE_CMD(SYSTEM_SHUTDOWN_INIT, 0) +#define SYS_SHUTDOWN_COMPLETE_CMD CREATE_CMD(SYSTEM_SHUTDOWN_COMPLETE, 0) +#define SYS_REBOOT_INIT_CMD CREATE_CMD(SYSTEM_REBOOT_INIT, 0) +#define SYS_REBOOT_COMPLETE_CMD CREATE_CMD(SYSTEM_REBOOT_COMPLETE, 0) + +#endif /* _TEGRA_HV_SYSMGR_H */ -- cgit v1.2.2