summaryrefslogtreecommitdiff
path: root/QcomModulePkg
diff options
context:
space:
mode:
authorlijuang <lijuang@codeaurora.org>2018-09-05 19:48:22 +0800
committerJeevan Shriram <jshriram@codeaurora.org>2018-11-15 11:23:56 -0800
commit31b93db28d7d25ec941fb39870ff2477b6be1ec6 (patch)
treeba8bbf855d1f9450775ead7d3d82034a20665612 /QcomModulePkg
parentf48193bee9ca96fbc3a640247201c94c326e9ce4 (diff)
QcomModulePkg: Add Arm Microvisor HVC functions and SCM call to get vm data
1. Add Arm64 Microvisor HVC calls to communicate with hypervisor and execute Linux Kernels. 2. Add scm call to get vm related data from hypervisor. Change-Id: I3930d324034fd5dccb290d6e60ea78c474d9b574
Diffstat (limited to 'QcomModulePkg')
-rw-r--r--QcomModulePkg/Include/Library/HypervisorMvCalls.h135
-rw-r--r--QcomModulePkg/Include/Protocol/scm_sip_interface.h26
-rw-r--r--QcomModulePkg/Library/BootLib/BootLib.inf3
-rw-r--r--QcomModulePkg/Library/BootLib/HypervisorMvCalls.c155
-rw-r--r--QcomModulePkg/QcomModulePkg.dsc3
5 files changed, 320 insertions, 2 deletions
diff --git a/QcomModulePkg/Include/Library/HypervisorMvCalls.h b/QcomModulePkg/Include/Library/HypervisorMvCalls.h
new file mode 100644
index 0000000000..3257af0749
--- /dev/null
+++ b/QcomModulePkg/Include/Library/HypervisorMvCalls.h
@@ -0,0 +1,135 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* The msg_id consists of the following bit fields: */
+/* bit 31 (0=client, 1=server) */
+/* bit 30..24 (protocol_id) */
+/* bit 23..16 (reserved) */
+/* bit 15.. 0 (function_id) */
+
+/* start_client: Unmap the client (ML VM) memory and start Linux */
+#define BOOT_MGR_START_CLIENT 0x00420001
+/* boot_mgr: struct HypBootMgrStartParams */
+
+/* start_client_reply: Response to BOOT_MGR_START_CLIENT */
+#define BOOT_MGR_START_CLIENT_REPLY 0x80420001
+/* boot_mgr: BOOLEAN success */
+
+/* start_self: Reset the caller and start the loaded HLOS image */
+#define BOOT_MGR_START_SELF 0x00420002
+/* boot_mgr: struct HypBootMgrStartParams */
+
+/*
+ * start_self_reply: Response to BOOT_MGR_START_CLIENT; sent only on
+ * failure as the caller will be reset if this call succeeds
+ */
+#define BOOT_MGR_START_SELF_REPLY 0x80420002
+/* boot_mgr: BOOLEAN success */
+
+#define HYP_BOOTINFO_MAGIC 0xC06B0071
+#define HYP_BOOTINFO_VERSION 1
+
+#define HYP_VM_TYPE_NONE 0
+#define HYP_VM_TYPE_APP 1 /* Light weight - no OS C VM */
+#define HYP_VM_TYPE_LINUX_AARCH64 2
+
+#define MAX_SUPPORTED_VMS 2
+#define MIN_SUPPORTED_VMS 1
+#define KERNEL_ADDR_IDX 0
+#define RAMDISK_ADDR_IDX 1
+#define DTB_ADDR_IDX 2
+
+#define GET_PIPE_ID_SEND(x) ((x) & (0xFFFF))
+#define GET_PIPE_ID_RECEIVE(x) (((x) >> 16) & (0xFFFF))
+
+/*
+DDR regions.
+* Unused regions have base = 0, size = 0.
+*/
+typedef struct vm_mem_region {
+ UINT64 base;
+ UINT64 size;
+}VmMemRegion __attribute__ ((packed));
+
+typedef struct hyp_boot_info {
+ UINT32 hyp_bootinfo_magic;
+ UINT32 hyp_bootinfo_version;
+ /* Size of this structure, in bytes */
+ UINT32 hyp_bootinfo_size;
+ /* the number of VMs controlled by the resource manager */
+ UINT32 num_vms;
+ /* the index of the HLOS VM */
+ UINT32 hlos_vm;
+ /* to communicate with resource manager */
+ UINT32 pipe_id;
+ /* for future extension */
+ UINT32 reserved_0[2];
+
+ struct {
+ /* HYP_VM_TYPE_ */
+ UINT32 vm_type;
+ /* vm name - e.g. for partition name matching */
+ CHAR8 vm_name[28];
+ /* uuid currently unused */
+ CHAR8 uuid[16];
+ union {
+ struct {
+ UINT64 dtbo_base;
+ UINT64 dtbo_size;
+ } linux_arm;
+ /* union padding */
+ UINT32 vm_info[12];
+ } info;
+ /* ddr ranges for the VM */
+ /* (areas valid for loading the kernel/dtb/initramfs) */
+ struct vm_mem_region ddr_region[8];
+ } vm[];
+}HypBootInfo __attribute__ ((packed));
+
+typedef struct HypBootMgrStartParams {
+ UINT64 EntryAddr; /* Physical load address / entry point of Linux */
+ UINT64 DtbAddr; /* Physical address of DTB */
+ BOOLEAN Is64BitMode; /* True to reset VM to AArch64 mode, false for AArch32 */
+} HypBootMgrStartParams;
+
+typedef struct HypMsg {
+ UINT32 MsgId;
+ union {
+ BOOLEAN Success;
+ struct HypBootMgrStartParams StartParams;
+ /* Content depends on msg_id; see table below */
+ } HypBootMgr;
+} HypMsg;
+
+#define CONTROL_STATE 3
+/* hypervisor calls */
+UINT32 HvcSysPipeSend (UINT32 PipeId, UINT32 Size, CONST UINT8 *Data);
+UINT32 HvcSysPipeControl (UINT32 PipeId, UINT32 Control);
+/* SCM call related functions */
+HypBootInfo *GetVmData (VOID);
+BOOLEAN IsVmEnabled (VOID);
diff --git a/QcomModulePkg/Include/Protocol/scm_sip_interface.h b/QcomModulePkg/Include/Protocol/scm_sip_interface.h
index 65629c729d..73ae574d69 100644
--- a/QcomModulePkg/Include/Protocol/scm_sip_interface.h
+++ b/QcomModulePkg/Include/Protocol/scm_sip_interface.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017 - 2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -1644,6 +1644,28 @@
TZ_SYSCALL_PARAM_TYPE_VAL)
/**
+ @ingroup hyp_info_get_hyp_dtb_address
+ Syscall trapped by hypervisor and will provide the address of the
+ HypBootInfo structure. If syscall reaches to TZ, TZ will return
+ syacll not found.
+
+ @smc_id
+ 0x02000609
+
+ @param_id
+ 0x00000000
+
+ @return
+ Return E-SUCCESS & HypBootInfo address if sucess / failure.
+*/
+
+#define HYP_INFO_GET_HYP_DTB_ADDRESS_ID \
+ TZ_SYSCALL_CREATE_SMC_ID (TZ_OWNER_SIP, TZ_SVC_INFO, 0x09)
+
+#define HYP_INFO_GET_HYP_DTB_ADDRESS_ID_PARAM_ID \
+ TZ_SYSCALL_CREATE_PARAM_ID_0
+
+/**
@ingroup decrypt_image
Parses the XML in the encrypted bootloader image and
@@ -4679,6 +4701,8 @@ typedef struct hyp_memprot_dstVM_perm_info_s {
UINT64 ctxsize; /**< size of ctx buffer in bytes */
+ UINT64 reserved;
+
} __attribute__ ((packed)) hyp_memprot_dstVM_perm_info_t;
/** @} */ /* end_weakgroup */
diff --git a/QcomModulePkg/Library/BootLib/BootLib.inf b/QcomModulePkg/Library/BootLib/BootLib.inf
index ad5c6fc0ae..685d17b354 100644
--- a/QcomModulePkg/Library/BootLib/BootLib.inf
+++ b/QcomModulePkg/Library/BootLib/BootLib.inf
@@ -40,7 +40,7 @@
GCC:*_*_*_CC_FLAGS = $(LLVM_ENABLE_SAFESTACK) $(LLVM_SAFESTACK_USE_PTR) $(LLVM_SAFESTACK_COLORING)
[BuildOptions.AARCH64]
- GCC:*_*_*_CC_FLAGS = -O2 $(SDLLVM_COMPILE_ANALYZE) $(SDLLVM_ANALYZE_REPORT)
+ GCC:*_*_*_CC_FLAGS = -O2 $(SDLLVM_COMPILE_ANALYZE) $(SDLLVM_ANALYZE_REPORT) -Wno-asm-operand-widths
GCC:*_*_*_CC_FLAGS = $(UBSAN_UEFI_GCC_FLAG_UNDEFINED)
GCC:*_*_*_CC_FLAGS = $(UBSAN_UEFI_GCC_FLAG_ALIGNMENT)
@@ -66,6 +66,7 @@
Rtic.c
PartialGoods.c
LECmdLine.c
+ HypervisorMvCalls.c
[Packages]
ArmPkg/ArmPkg.dec
diff --git a/QcomModulePkg/Library/BootLib/HypervisorMvCalls.c b/QcomModulePkg/Library/BootLib/HypervisorMvCalls.c
new file mode 100644
index 0000000000..8dd26fe188
--- /dev/null
+++ b/QcomModulePkg/Library/BootLib/HypervisorMvCalls.c
@@ -0,0 +1,155 @@
+/* Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided
+ * with the distribution.
+ * * Neither the name of The Linux Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "BootLinux.h"
+#include <Library/DebugLib.h>
+#include <Protocol/EFIScm.h>
+#include <Protocol/scm_sip_interface.h>
+#include <Library/HypervisorMvCalls.h>
+
+STATIC BOOLEAN VmEnabled = FALSE;
+STATIC HypBootInfo *HypInfo = NULL;
+
+BOOLEAN IsVmEnabled (VOID)
+{
+ return VmEnabled;
+}
+
+HypBootInfo *GetVmData (VOID)
+{
+ EFI_STATUS Status;
+ QCOM_SCM_PROTOCOL *QcomScmProtocol = NULL;
+ UINT64 Parameters[SCM_MAX_NUM_PARAMETERS] = {0};
+ UINT64 Results[SCM_MAX_NUM_RESULTS] = {0};
+
+ if (IsVmEnabled ()) {
+ return HypInfo;
+ }
+
+ DEBUG ((EFI_D_INFO, "GetVmData: making ScmCall to get HypInfo\n"));
+ /* Locate QCOM_SCM_PROTOCOL */
+ Status = gBS->LocateProtocol (&gQcomScmProtocolGuid, NULL,
+ (VOID **)&QcomScmProtocol);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "GetVmData: Locate SCM Protocol failed, "
+ "Status: (0x%x)\n", Status));
+ return NULL;
+ }
+
+ /* Make ScmSipSysCall */
+ Status = QcomScmProtocol->ScmSipSysCall (
+ QcomScmProtocol, HYP_INFO_GET_HYP_DTB_ADDRESS_ID,
+ HYP_INFO_GET_HYP_DTB_ADDRESS_ID_PARAM_ID, Parameters, Results);
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "GetVmData: No Vm data present! "
+ "Status = (0x%x)\n", Status));
+ return NULL;
+ }
+
+ HypInfo = (HypBootInfo *)Results[1];
+ if (!HypInfo) {
+ DEBUG ((EFI_D_ERROR, "GetVmData: ScmSipSysCall returned NULL\n"));
+ return NULL;
+ }
+ VmEnabled = TRUE;
+
+ return HypInfo;
+}
+
+/* From Linux Kernel asm/system.h */
+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+/**
+ *
+ * Control a pipe, including reset, ready and halt functionality.
+ *
+ * @param pipe_id
+ * The capability identifier of the pipe.
+ * @param control
+ * The state control argument.
+ *
+ * @retval error
+ * The returned error code.
+ *
+ */
+UINT32 HvcSysPipeControl (UINT32 PipeId, UINT32 Control)
+{
+#if TARGET_ARCH_ARM64
+ register UINT32 x0 __asm__ ("x0") = (UINT32) PipeId;
+ register UINT32 x1 __asm__ ("x1") = (UINT32) Control;
+ __asm__ __volatile__ (
+ __asmeq ("%0", "x0")
+ __asmeq ("%1", "x1")
+ "hvc #5146 \n\t"
+ : "+r" (x0), "+r" (x1)
+ :
+ : "cc", "memory", "x2", "x3", "x4", "x5"
+ );
+
+ return (UINT32)x0;
+#endif
+ return 0;
+}
+
+/**
+ *
+ * Send a message to a microvisor pipe.
+ *
+ * @param pipe_id
+ * The capability identifier of the pipe.
+ * @param size
+ * Size of the message to send.
+ * @param data
+ * Pointer to the message payload to send.
+ *
+ * @retval error
+ * The returned error code.
+ *
+ */
+UINT32 HvcSysPipeSend (UINT32 PipeId, UINT32 Size, CONST UINT8 *Data)
+{
+#if TARGET_ARCH_ARM64
+ register UINT32 x0 __asm__ ("x0") = (UINT32) PipeId;
+ register UINT32 x1 __asm__ ("x1") = (UINT32) Size;
+ register UINT32 x2 __asm__ ("x2") = (UINT32)(UINTN) Data;
+ __asm__ __volatile__ (
+ __asmeq ("%0", "x0")
+ __asmeq ("%1", "x1")
+ __asmeq ("%2", "x2")
+ "hvc #5148 \n\t"
+ : "+r" (x0), "+r" (x1), "+r" (x2)
+ :
+ : "cc", "memory", "x3", "x4", "x5"
+ );
+
+
+ return (UINT32)x0;
+#endif
+ return 0;
+}
diff --git a/QcomModulePkg/QcomModulePkg.dsc b/QcomModulePkg/QcomModulePkg.dsc
index 3d45af50b2..fbbb578353 100644
--- a/QcomModulePkg/QcomModulePkg.dsc
+++ b/QcomModulePkg/QcomModulePkg.dsc
@@ -126,6 +126,9 @@
!ifdef $(INIT_BIN)
GCC:*_*_*_CC_FLAGS = -DINIT_BIN='$(INIT_BIN)'
!endif
+ !if $(TARGET_ARCH_ARM64)
+ GCC:*_*_*_CC_FLAGS = -DTARGET_ARCH_ARM64
+ !endif
[PcdsFixedAtBuild.common]