diff --git a/docs/components/arm-sip-service.rst b/docs/components/arm-sip-service.rst index 2d58586b9..01bc04d71 100644 --- a/docs/components/arm-sip-service.rst +++ b/docs/components/arm-sip-service.rst @@ -17,6 +17,7 @@ The Arm SiP implementation offers the following services: - Performance Measurement Framework (PMF) - Execution State Switching service +- DebugFS interface Source definitions for Arm SiP service are located in the ``arm_sip_svc.h`` header file. @@ -87,6 +88,346 @@ Instead, execution starts at the supplied entry point, with the CPU registers 0 and 1 populated with the supplied *Cookie hi* and *Cookie lo* values, respectively. +DebugFS interface +----------------- + +The optional DebugFS interface is accessed through an SMC SiP service. Refer +to the component documentation for details. + +String parameters are passed through a shared buffer using a specific union: + +.. code:: c + + union debugfs_parms { + struct { + char fname[MAX_PATH_LEN]; + } open; + + struct mount { + char srv[MAX_PATH_LEN]; + char where[MAX_PATH_LEN]; + char spec[MAX_PATH_LEN]; + } mount; + + struct { + char path[MAX_PATH_LEN]; + dir_t dir; + } stat; + + struct { + char oldpath[MAX_PATH_LEN]; + char newpath[MAX_PATH_LEN]; + } bind; + }; + +Format of the dir_t structure as such: + +.. code:: c + + typedef struct { + char name[NAMELEN]; + long length; + unsigned char mode; + unsigned char index; + unsigned char dev; + qid_t qid; + } dir_t; + + +* Identifiers + +======================== ============================================= +SMC_OK 0 +SMC_UNK -1 +DEBUGFS_E_INVALID_PARAMS -2 +======================== ============================================= + +======================== ============================================= +MOUNT 0 +CREATE 1 +OPEN 2 +CLOSE 3 +READ 4 +WRITE 5 +SEEK 6 +BIND 7 +STAT 8 +INIT 10 +VERSION 11 +======================== ============================================= + +MOUNT +~~~~~ + +Description +^^^^^^^^^^^ +This operation mounts a blob of data pointed to by path stored in `src`, at +filesystem location pointed to by path stored in `where`, using driver pointed +to by path in `spec`. + +Parameters +^^^^^^^^^^ +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``MOUNT`` +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if mount operation failed +=============== ========================================================== + +OPEN +~~~~ + +Description +^^^^^^^^^^^ +This operation opens the file path pointed to by `fname`. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``OPEN`` +uint32_t mode +======== ============================================================ + +mode can be one of: + +.. code:: c + + enum mode { + O_READ = 1 << 0, + O_WRITE = 1 << 1, + O_RDWR = 1 << 2, + O_BIND = 1 << 3, + O_DIR = 1 << 4, + O_STAT = 1 << 5 + }; + +Return values +^^^^^^^^^^^^^ + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if open operation failed + +uint32_t w1: file descriptor id on success. +=============== ========================================================== + +CLOSE +~~~~~ + +Description +^^^^^^^^^^^ + +This operation closes a file described by a file descriptor obtained by a +previous call to OPEN. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``CLOSE`` +uint32_t File descriptor id returned by OPEN +======== ============================================================ + +Return values +^^^^^^^^^^^^^ +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if close operation failed +=============== ========================================================== + +READ +~~~~ + +Description +^^^^^^^^^^^ + +This operation reads a number of bytes from a file descriptor obtained by +a previous call to OPEN. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``READ`` +uint32_t File descriptor id returned by OPEN +uint32_t Number of bytes to read +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +On success, the read data is retrieved from the shared buffer after the +operation. + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if read operation failed + +uint32_t w1: number of bytes read on success. +=============== ========================================================== + +SEEK +~~~~ + +Description +^^^^^^^^^^^ + +Move file pointer for file described by given `file descriptor` of given +`offset` related to `whence`. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``SEEK`` +uint32_t File descriptor id returned by OPEN +sint32_t offset in the file relative to whence +uint32_t whence +======== ============================================================ + +whence can be one of: + +========= ============================================================ +KSEEK_SET 0 +KSEEK_CUR 1 +KSEEK_END 2 +========= ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if seek operation failed +=============== ========================================================== + +BIND +~~~~ + +Description +^^^^^^^^^^^ + +Create a link from `oldpath` to `newpath`. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``BIND`` +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if bind operation failed +=============== ========================================================== + +STAT +~~~~ + +Description +^^^^^^^^^^^ + +Perform a stat operation on provided file `name` and returns the directory +entry statistics into `dir`. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``STAT`` +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ========================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if stat operation failed +=============== ========================================================== + +INIT +~~~~ + +Description +^^^^^^^^^^^ +Initial call to setup the shared exchange buffer. Notice if successful once, +subsequent calls fail after a first initialization. The caller maps the same +page frame in its virtual space and uses this buffer to exchange string +parameters with filesystem primitives. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``INIT`` +uint64_t Physical address of the shared buffer. +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ====================================================== +int32_t w0 == SMC_OK on success + + w0 == DEBUGFS_E_INVALID_PARAMS if already initialized, + or internal error occurred. +=============== ====================================================== + +VERSION +~~~~~~~ + +Description +^^^^^^^^^^^ +Returns the debugfs interface version if implemented in TF-A. + +Parameters +^^^^^^^^^^ + +======== ============================================================ +uint32_t FunctionID (0x82000030 / 0xC2000030) +uint32_t ``VERSION`` +======== ============================================================ + +Return values +^^^^^^^^^^^^^ + +=============== ====================================================== +int32_t w0 == SMC_OK on success + + w0 == SMC_UNK if interface is not implemented + +uint32_t w1: On success, debugfs interface version, 32 bits + value with major version number in upper 16 bits and + minor version in lower 16 bits. +=============== ====================================================== + +* CREATE(1) and WRITE (5) command identifiers are unimplemented and + return `SMC_UNK`. + -------------- *Copyright (c) 2017-2019, Arm Limited and Contributors. All rights reserved.* diff --git a/docs/components/debugfs-design.rst b/docs/components/debugfs-design.rst new file mode 100644 index 000000000..06916f3d9 --- /dev/null +++ b/docs/components/debugfs-design.rst @@ -0,0 +1,132 @@ +======== +Debug FS +======== + +.. contents:: + +Overview +-------- + +The *DebugFS* feature is primarily aimed at exposing firmware debug data to +higher SW layers such as a non-secure component. Such component can be the +TFTF test payload or a Linux kernel module. + +Virtual filesystem +------------------ + +The core functionality lies in a virtual file system based on a 9p file server +interface (`Notes on the Plan 9 Kernel Source`_). The implementation permits +exposing virtual files, firmware drivers, and file blobs. + +Namespace +~~~~~~~~~ + +Two namespaces are exposed: + + - # is used as root for drivers (e.g. #t0 is the first uart) + - / is used as root for virtual "files" (e.g. /fip, or /dev/uart) + +9p interface +~~~~~~~~~~~~ + +The associated primitives are: + +- Unix-like: + + - open(): create a file descriptor that acts as a handle to the file passed as + an argument. + - close(): close the file descriptor created by open(). + - read(): read from a file to a buffer. + - write(): write from a buffer to a file. + - seek(): set the file position indicator of a file descriptor either to a + relative or an absolute offset. + - stat(): get information about a file (type, mode, size, ...). + +.. code:: c + + int open(const char *name, int flags); + int close(int fd); + int read(int fd, void *buf, int n); + int write(int fd, void *buf, int n); + int seek(int fd, long off, int whence); + int stat(char *path, dir_t *dir); + +- Specific primitives : + + - mount(): create a link between a driver and spec. + - create(): create a file in a specific location. + - bind(): expose the content of a directory to another directory. + +.. code:: c + + int mount(char *srv, char *mnt, char *spec); + int create(const char *name, int flags); + int bind(char *path, char *where); + +This interface is embedded into the BL31 run-time payload when selected by build +options. The interface multiplexes drivers or emulated "files": + +- Debug data can be partitioned into different virtual files e.g. expose PMF + measurements through a file, and internal firmware state counters through + another file. +- This permits direct access to a firmware driver, mainly for test purposes + (e.g. a hardware device that may not be accessible to non-privileged/ + non-secure layers, or for which no support exists in the NS side). + +SMC interface +------------- + +The communication with the 9p layer in BL31 is made through an SMC conduit +(`SMC Calling Convention PDD`_), using a specific SiP Function Id. An NS shared +buffer is used to pass path string parameters, or e.g. to exchange data on a +read operation. Refer to `ARM SiP Services`_ for a description of the SMC +interface. + +Security considerations +----------------------- + +- Due to the nature of the exposed data, the feature is considered experimental + and importantly **shall only be used in debug builds**. +- Several primitive imply string manipulations and usage of string formats. +- Special care is taken with the shared buffer to avoid TOCTOU attacks. + +Limitations +----------- + +- In order to setup the shared buffer, the component consuming the interface + needs to allocate a physical page frame and transmit its address. +- In order to map the shared buffer, BL31 requires enabling the dynamic xlat + table option. +- Data exchange is limited by the shared buffer length. A large read operation + might be split into multiple read operations of smaller chunks. +- On concurrent access, a spinlock is implemented in the BL31 service to protect + the internal work buffer, and re-entrancy into the filesystem layers. +- Notice, a physical device driver if exposed by the firmware may conflict with + the higher level OS if the latter implements its own driver for the same + physical device. + +Applications +------------ + +The SMC interface is accessible from an NS environment, that is: + +- a test payload, bootloader or hypervisor running at NS-EL2 +- a Linux kernel driver running at NS-EL1 +- a Linux userspace application through the kernel driver + +References +---------- + +.. [#] `SMC Calling Convention PDD`_ +.. [#] `Notes on the Plan 9 Kernel Source`_ +.. [#] `Linux 9p remote filesystem protocol`_ +.. [#] `ARM SiP Services`_ + +-------------- + +*Copyright (c) 2019, Arm Limited and Contributors. All rights reserved.* + +.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ +.. _Notes on the Plan 9 Kernel Source: http://lsub.org/who/nemo/9.pdf +.. _Linux 9p remote filesystem protocol: https://www.kernel.org/doc/Documentation/filesystems/9p.txt +.. _ARM SiP Services: arm-sip-service.rst diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 051586bc3..469fd34b7 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -544,6 +544,10 @@ Common build options (Coherent memory region is included) or 0 (Coherent memory region is excluded). Default is 1. +- ``USE_DEBUGFS``: When set to 1 this option activates an EXPERIMENTAL feature + exposing a virtual filesystem interface through BL31 as a SiP SMC function. + Default is 0. + - ``USE_ROMLIB``: This flag determines whether library at ROM will be used. This feature creates a library of functions to be placed in ROM and thus reduces SRAM usage. Refer to :ref:`Library at ROM` for further details. Default diff --git a/include/lib/debugfs.h b/include/lib/debugfs.h index b7e33303c..8ed237ae2 100644 --- a/include/lib/debugfs.h +++ b/include/lib/debugfs.h @@ -56,5 +56,28 @@ int stat(const char *path, dir_t *dir); /* DebugFS initialization */ void debugfs_init(void); +int debugfs_smc_setup(void); + +/* Debugfs version returned through SMC interface */ +#define DEBUGFS_VERSION (0x000000001U) + +/* Function ID for accessing the debugfs interface */ +#define DEBUGFS_FID_VALUE (0x30U) + +#define is_debugfs_fid(_fid) \ + (((_fid) & FUNCID_NUM_MASK) == DEBUGFS_FID_VALUE) + +/* Error code for debugfs SMC interface failures */ +#define DEBUGFS_E_INVALID_PARAMS (-2) +#define DEBUGFS_E_DENIED (-3) + +uintptr_t debugfs_smc_handler(unsigned int smc_fid, + u_register_t cmd, + u_register_t arg2, + u_register_t arg3, + u_register_t arg4, + void *cookie, + void *handle, + uintptr_t flags); #endif /* DEBUGFS_H */ diff --git a/include/plat/arm/common/arm_sip_svc.h b/include/plat/arm/common/arm_sip_svc.h index 16573ce6a..85fdb289f 100644 --- a/include/plat/arm/common/arm_sip_svc.h +++ b/include/plat/arm/common/arm_sip_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,9 +16,15 @@ /* U(0x8200ff02) is reserved */ #define ARM_SIP_SVC_VERSION U(0x8200ff03) +/* PMF_SMC_GET_TIMESTAMP_32 0x82000010 */ +/* PMF_SMC_GET_TIMESTAMP_64 0xC2000010 */ + /* Function ID for requesting state switch of lower EL */ #define ARM_SIP_SVC_EXE_STATE_SWITCH U(0x82000020) +/* DEBUGFS_SMC_32 0x82000030U */ +/* DEBUGFS_SMC_64 0xC2000030U */ + /* ARM SiP Service Calls version numbers */ #define ARM_SIP_SVC_VERSION_MAJOR U(0x0) #define ARM_SIP_SVC_VERSION_MINOR U(0x2) diff --git a/lib/debugfs/debugfs.mk b/lib/debugfs/debugfs.mk index 2c0260006..138fc72a1 100644 --- a/lib/debugfs/debugfs.mk +++ b/lib/debugfs/debugfs.mk @@ -9,3 +9,5 @@ DEBUGFS_SRCS := $(addprefix lib/debugfs/, \ devc.c \ devroot.c \ devfip.c) + +DEBUGFS_SRCS += lib/debugfs/debugfs_smc.c diff --git a/lib/debugfs/debugfs_smc.c b/lib/debugfs/debugfs_smc.c new file mode 100644 index 000000000..400c166d7 --- /dev/null +++ b/lib/debugfs/debugfs_smc.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define MAX_PATH_LEN 256 + +#define MOUNT 0 +#define CREATE 1 +#define OPEN 2 +#define CLOSE 3 +#define READ 4 +#define WRITE 5 +#define SEEK 6 +#define BIND 7 +#define STAT 8 +#define INIT 10 +#define VERSION 11 + +/* This is the virtual address to which we map the NS shared buffer */ +#define DEBUGFS_SHARED_BUF_VIRT ((void *)0x81000000U) + +static union debugfs_parms { + struct { + char fname[MAX_PATH_LEN]; + } open; + + struct { + char srv[MAX_PATH_LEN]; + char where[MAX_PATH_LEN]; + char spec[MAX_PATH_LEN]; + } mount; + + struct { + char path[MAX_PATH_LEN]; + dir_t dir; + } stat; + + struct { + char oldpath[MAX_PATH_LEN]; + char newpath[MAX_PATH_LEN]; + } bind; +} parms; + +/* debugfs_access_lock protects shared buffer and internal */ +/* FS functions from concurrent acccesses. */ +static spinlock_t debugfs_access_lock; + +static bool debugfs_initialized; + +uintptr_t debugfs_smc_handler(unsigned int smc_fid, + u_register_t cmd, + u_register_t arg2, + u_register_t arg3, + u_register_t arg4, + void *cookie, + void *handle, + u_register_t flags) +{ + int64_t smc_ret = DEBUGFS_E_INVALID_PARAMS, smc_resp = 0; + int ret; + + /* Allow calls from non-secure only */ + if (is_caller_secure(flags)) { + SMC_RET1(handle, DEBUGFS_E_DENIED); + } + + /* Expect a SiP service fast call */ + if ((GET_SMC_TYPE(smc_fid) != SMC_TYPE_FAST) || + (GET_SMC_OEN(smc_fid) != OEN_SIP_START)) { + SMC_RET1(handle, SMC_UNK); + } + + /* Truncate parameters if 32b SMC convention call */ + if (GET_SMC_CC(smc_fid) == SMC_32) { + arg2 &= 0xffffffff; + arg3 &= 0xffffffff; + arg4 &= 0xffffffff; + } + + spin_lock(&debugfs_access_lock); + + if (debugfs_initialized == true) { + /* Copy NS shared buffer to internal secure location */ + memcpy(&parms, (void *)DEBUGFS_SHARED_BUF_VIRT, + sizeof(union debugfs_parms)); + } + + switch (cmd) { + case INIT: + if (debugfs_initialized == false) { + /* TODO: check PA validity e.g. whether */ + /* it is an NS region. */ + ret = mmap_add_dynamic_region(arg2, + (uintptr_t)DEBUGFS_SHARED_BUF_VIRT, + PAGE_SIZE_4KB, + MT_MEMORY | MT_RW | MT_NS); + if (ret == 0) { + debugfs_initialized = true; + smc_ret = SMC_OK; + smc_resp = 0; + } + } + break; + + case VERSION: + smc_ret = SMC_OK; + smc_resp = DEBUGFS_VERSION; + break; + + case MOUNT: + ret = mount(parms.mount.srv, + parms.mount.where, + parms.mount.spec); + if (ret == 0) { + smc_ret = SMC_OK; + smc_resp = 0; + } + break; + + case OPEN: + ret = open(parms.open.fname, arg2); + if (ret >= 0) { + smc_ret = SMC_OK; + smc_resp = ret; + } + break; + + case CLOSE: + ret = close(arg2); + if (ret == 0) { + smc_ret = SMC_OK; + smc_resp = 0; + } + break; + + case READ: + ret = read(arg2, DEBUGFS_SHARED_BUF_VIRT, arg3); + if (ret >= 0) { + smc_ret = SMC_OK; + smc_resp = ret; + } + break; + + case SEEK: + ret = seek(arg2, arg3, arg4); + if (ret == 0) { + smc_ret = SMC_OK; + smc_resp = 0; + } + break; + + case BIND: + ret = bind(parms.bind.oldpath, parms.bind.newpath); + if (ret == 0) { + smc_ret = SMC_OK; + smc_resp = 0; + } + break; + + case STAT: + ret = stat(parms.stat.path, &parms.stat.dir); + if (ret == 0) { + memcpy((void *)DEBUGFS_SHARED_BUF_VIRT, &parms, + sizeof(union debugfs_parms)); + smc_ret = SMC_OK; + smc_resp = 0; + } + break; + + /* Not implemented */ + case CREATE: + /* Intentional fall-through */ + + /* Not implemented */ + case WRITE: + /* Intentional fall-through */ + + default: + smc_ret = SMC_UNK; + smc_resp = 0; + } + + spin_unlock(&debugfs_access_lock); + + SMC_RET2(handle, smc_ret, smc_resp); + + /* Not reached */ + return smc_ret; +} + +int debugfs_smc_setup(void) +{ + debugfs_initialized = false; + debugfs_access_lock.lock = 0; + + return 0; +} diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index a94879624..5c0df7a7d 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -122,6 +122,10 @@ const mmap_region_t plat_arm_mmap[] = { #ifdef IMAGE_BL31 const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, +#if USE_DEBUGFS + /* Required by devfip, can be removed if devfip is not used */ + V2M_MAP_FLASH0_RW, +#endif /* USE_DEBUGFS */ ARM_MAP_EL3_TZC_DRAM, V2M_MAP_IOFPGA, MAP_DEVICE0, diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 98dd0a97f..2b441747a 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -68,7 +68,11 @@ # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# if USE_DEBUGFS +# define MAX_XLAT_TABLES 6 +# else +# define MAX_XLAT_TABLES 5 +# endif # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 3a9972bb4..8cf2612a7 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -291,6 +291,10 @@ else # if AArch64 endif endif +ifeq (${USE_DEBUGFS},1) + BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 +endif + # Add support for platform supplied linker script for BL31 build $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index ab90f46a8..939885f98 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -231,6 +232,10 @@ void arm_bl31_platform_setup(void) #if RAS_EXTENSION ras_init(); #endif + +#if USE_DEBUGFS + debugfs_init(); +#endif /* USE_DEBUGFS */ } /******************************************************************************* diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c index 3d308a335..c8f480f18 100644 --- a/plat/arm/common/arm_sip_svc.c +++ b/plat/arm/common/arm_sip_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -20,8 +21,18 @@ DEFINE_SVC_UUID2(arm_sip_svc_uid, static int arm_sip_setup(void) { - if (pmf_setup() != 0) + if (pmf_setup() != 0) { return 1; + } + +#if USE_DEBUGFS + + if (debugfs_smc_setup() != 0) { + return 1; + } + +#endif /* USE_DEBUGFS */ + return 0; } @@ -48,6 +59,15 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid, handle, flags); } +#if USE_DEBUGFS + + if (is_debugfs_fid(smc_fid)) { + return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } + +#endif /* USE_DEBUGFS */ + switch (smc_fid) { case ARM_SIP_SVC_EXE_STATE_SWITCH: { u_register_t pc;