profiler: Add a communication interface between userspace and tz services
Add snapshot of profiler driver from msm-4.4. This snapshot is taken as of msm-4.4 commit bf01369440c0 (profiler: Add a communication interface between userspace and tz services) Refine code for llcc support and use API in kernel 5.4. Change-Id: Icc545138781c26a82ae6234965cb975b11b7079e Signed-off-by: Lei wang <leiwan@codeaurora.org>
This commit is contained in:
parent
629f831242
commit
0675c71004
@ -2478,6 +2478,27 @@ int __init scm_mem_protection_init_do(struct device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
int __qcom_scm_ddrbw_profiler(struct device *dev, phys_addr_t in_buf,
|
||||
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size)
|
||||
{
|
||||
int ret;
|
||||
struct qcom_scm_desc desc = {
|
||||
.svc = QCOM_SCM_SVC_INFO,
|
||||
.cmd = TZ_SVC_BW_PROF_ID,
|
||||
.owner = ARM_SMCCC_OWNER_SIP,
|
||||
};
|
||||
|
||||
desc.args[0] = in_buf;
|
||||
desc.args[1] = in_buf_size;
|
||||
desc.args[2] = out_buf;
|
||||
desc.args[3] = out_buf_size;
|
||||
desc.arginfo = QCOM_SCM_ARGS(4, QCOM_SCM_RW, QCOM_SCM_VAL, QCOM_SCM_RW,
|
||||
QCOM_SCM_VAL);
|
||||
ret = qcom_scm_call(dev, &desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void __qcom_scm_init(void)
|
||||
{
|
||||
|
||||
|
@ -1059,6 +1059,14 @@ int qcom_scm_qseecom_call_noretry(u32 cmd_id, struct scm_desc *desc)
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_qseecom_call_noretry);
|
||||
|
||||
int qcom_scm_ddrbw_profiler(phys_addr_t in_buf,
|
||||
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size)
|
||||
{
|
||||
return __qcom_scm_ddrbw_profiler(__scm ? __scm->dev : NULL, in_buf,
|
||||
in_buf_size, out_buf, out_buf_size);
|
||||
}
|
||||
EXPORT_SYMBOL(qcom_scm_ddrbw_profiler);
|
||||
|
||||
/**
|
||||
* qcom_scm_is_available() - Checks if SCM is available
|
||||
*/
|
||||
|
@ -288,6 +288,10 @@ extern int __init scm_mem_protection_init_do(struct device *dev);
|
||||
|
||||
#endif
|
||||
|
||||
#define TZ_SVC_BW_PROF_ID 0x07 /* ddr profiler */
|
||||
extern int __qcom_scm_ddrbw_profiler(struct device *dev, phys_addr_t in_buf,
|
||||
size_t in_buf_size, phys_addr_t out_buf, size_t out_buf_size);
|
||||
|
||||
/* common error codes */
|
||||
#define QCOM_SCM_V2_EBUSY -12
|
||||
#define QCOM_SCM_ENOMEM -5
|
||||
|
@ -499,6 +499,14 @@ config HDCP_QSEECOM
|
||||
via the QSEECOM Driver and also communicates with the Receiver via
|
||||
APIs exposed by the interface driver.
|
||||
|
||||
config PROFILER
|
||||
tristate "Qualcomm Technologies, Inc. trustzone Communicator driver"
|
||||
help
|
||||
Provides a communication interface between userspace and
|
||||
trustzone using Secure Channel Manager (SCM) interface.
|
||||
It exposes APIs for userspace to get system profiling
|
||||
information.
|
||||
|
||||
config WIGIG_SENSING_SPI
|
||||
tristate "Sensing over 60GHz using wil6210 / SPI bus"
|
||||
depends on SPI && WIL6210
|
||||
|
@ -62,5 +62,6 @@ obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o
|
||||
obj-$(CONFIG_QSEECOM) += qseecom-mod.o
|
||||
qseecom-mod-y := qseecom.o
|
||||
qseecom-mod-$(CONFIG_COMPAT) += compat_qseecom.o
|
||||
obj-$(CONFIG_PROFILER) += profiler.o
|
||||
obj-$(CONFIG_WIGIG_SENSING_SPI) += wigig_sensing.o
|
||||
obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o
|
||||
|
352
drivers/misc/profiler.c
Normal file
352
drivers/misc/profiler.c
Normal file
@ -0,0 +1,352 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, 2020-2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "PROFILER: %s: " fmt, __func__
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <soc/qcom/profiler.h>
|
||||
|
||||
#include <linux/qtee_shmbridge.h>
|
||||
#include <linux/qcom_scm.h>
|
||||
|
||||
#define PROFILER_DEV "profiler"
|
||||
|
||||
static struct class *driver_class;
|
||||
static dev_t profiler_device_no;
|
||||
|
||||
struct profiler_control {
|
||||
struct device *pdev;
|
||||
struct cdev cdev;
|
||||
};
|
||||
|
||||
static struct profiler_control profiler;
|
||||
|
||||
struct profiler_dev_handle {
|
||||
bool released;
|
||||
int abort;
|
||||
};
|
||||
|
||||
static int bw_profiling_command(const void *req)
|
||||
{
|
||||
int ret = 0;
|
||||
uint32_t qseos_cmd_id = 0;
|
||||
struct tz_bw_svc_resp *rsp = NULL;
|
||||
size_t req_size = 0, rsp_size = 0;
|
||||
struct qtee_shm bw_shm = {0};
|
||||
|
||||
rsp = &((struct tz_bw_svc_buf *)req)->bwresp;
|
||||
rsp_size = sizeof(struct tz_bw_svc_resp);
|
||||
req_size = ((struct tz_bw_svc_buf *)req)->req_size;
|
||||
|
||||
if (!req || !rsp) {
|
||||
pr_err("Invalid buffer pointer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
qseos_cmd_id = *(uint32_t *)req;
|
||||
|
||||
ret = qtee_shmbridge_allocate_shm(PAGE_ALIGN(req_size + rsp_size), &bw_shm);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("shmbridge alloc failed for in msg in release\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
memcpy(bw_shm.vaddr, req, req_size);
|
||||
qtee_shmbridge_flush_shm_buf(&bw_shm);
|
||||
|
||||
switch (qseos_cmd_id) {
|
||||
case TZ_BW_SVC_START_ID:
|
||||
case TZ_BW_SVC_GET_ID:
|
||||
case TZ_BW_SVC_STOP_ID:
|
||||
/* Send the command to TZ */
|
||||
ret = qcom_scm_ddrbw_profiler(bw_shm.paddr, req_size,
|
||||
bw_shm.paddr + req_size, rsp_size);
|
||||
break;
|
||||
default:
|
||||
pr_err("cmd_id %d is not supported.\n",
|
||||
qseos_cmd_id);
|
||||
ret = -EINVAL;
|
||||
} /*end of switch (qsee_cmd_id) */
|
||||
|
||||
qtee_shmbridge_inv_shm_buf(&bw_shm);
|
||||
memcpy(rsp, (char *)bw_shm.vaddr + req_size, rsp_size);
|
||||
out:
|
||||
qtee_shmbridge_free_shm(&bw_shm);
|
||||
/* Verify cmd id and Check that request succeeded.*/
|
||||
if ((rsp->status != E_BW_SUCCESS) ||
|
||||
(qseos_cmd_id != rsp->cmd_id)) {
|
||||
ret = -1;
|
||||
pr_err("Status: %d,Cmd: %d\n",
|
||||
rsp->status,
|
||||
rsp->cmd_id);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bw_profiling_start(struct tz_bw_svc_buf *bwbuf)
|
||||
{
|
||||
bwbuf->bwreq.start_req.cmd_id = TZ_BW_SVC_START_ID;
|
||||
bwbuf->bwreq.start_req.version = TZ_BW_SVC_VERSION;
|
||||
bwbuf->req_size = sizeof(struct tz_bw_svc_start_req);
|
||||
return bw_profiling_command(bwbuf);
|
||||
}
|
||||
|
||||
static int bw_profiling_get(void __user *argp, struct tz_bw_svc_buf *bwbuf)
|
||||
{
|
||||
int ret;
|
||||
const int bufsize = sizeof(struct profiler_bw_cntrs_req)
|
||||
- sizeof(uint32_t);
|
||||
struct profiler_bw_cntrs_req cnt_buf;
|
||||
struct qtee_shm buf_shm = {0};
|
||||
|
||||
memset(&cnt_buf, 0, sizeof(cnt_buf));
|
||||
/* Allocate memory for get buffer */
|
||||
ret = qtee_shmbridge_allocate_shm(PAGE_ALIGN(bufsize), &buf_shm);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
pr_err("shmbridge alloc buf failed\n");
|
||||
goto out;
|
||||
}
|
||||
/* Populate request data */
|
||||
bwbuf->bwreq.get_req.cmd_id = TZ_BW_SVC_GET_ID;
|
||||
bwbuf->bwreq.get_req.buf_ptr = buf_shm.paddr;
|
||||
bwbuf->bwreq.get_req.buf_size = bufsize;
|
||||
bwbuf->req_size = sizeof(struct tz_bw_svc_get_req);
|
||||
qtee_shmbridge_flush_shm_buf(&buf_shm);
|
||||
ret = bw_profiling_command(bwbuf);
|
||||
if (ret) {
|
||||
pr_err("bw_profiling_command failed\n");
|
||||
goto out;
|
||||
}
|
||||
qtee_shmbridge_inv_shm_buf(&buf_shm);
|
||||
memcpy(&cnt_buf, buf_shm.vaddr, bufsize);
|
||||
if (copy_to_user(argp, &cnt_buf, sizeof(struct profiler_bw_cntrs_req)))
|
||||
pr_err("copy_to_user failed\n");
|
||||
out:
|
||||
/* Free memory for response */
|
||||
qtee_shmbridge_free_shm(&buf_shm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int bw_profiling_stop(struct tz_bw_svc_buf *bwbuf)
|
||||
{
|
||||
bwbuf->bwreq.stop_req.cmd_id = TZ_BW_SVC_STOP_ID;
|
||||
bwbuf->req_size = sizeof(struct tz_bw_svc_stop_req);
|
||||
return bw_profiling_command(bwbuf);
|
||||
}
|
||||
|
||||
static int profiler_get_bw_info(void __user *argp)
|
||||
{
|
||||
int ret = 0;
|
||||
struct tz_bw_svc_buf *bwbuf = NULL;
|
||||
struct profiler_bw_cntrs_req cnt_buf;
|
||||
|
||||
ret = copy_from_user(&cnt_buf, argp,
|
||||
sizeof(struct profiler_bw_cntrs_req));
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Allocate memory for request */
|
||||
bwbuf = kzalloc(sizeof(struct tz_bw_svc_buf), GFP_KERNEL);
|
||||
if (bwbuf == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
switch (cnt_buf.cmd) {
|
||||
case TZ_BW_SVC_START_ID:
|
||||
ret = bw_profiling_start(bwbuf);
|
||||
if (ret)
|
||||
pr_err("bw_profiling_start Failed with ret: %d\n", ret);
|
||||
break;
|
||||
case TZ_BW_SVC_GET_ID:
|
||||
ret = bw_profiling_get(argp, bwbuf);
|
||||
if (ret)
|
||||
pr_err("bw_profiling_get Failed with ret: %d\n", ret);
|
||||
break;
|
||||
case TZ_BW_SVC_STOP_ID:
|
||||
ret = bw_profiling_stop(bwbuf);
|
||||
if (ret)
|
||||
pr_err("bw_profiling_stop Failed with ret: %d\n", ret);
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid IOCTL: 0x%x\n", cnt_buf.cmd);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
/* Free memory for command */
|
||||
if (bwbuf != NULL) {
|
||||
kfree(bwbuf);
|
||||
bwbuf = NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int profiler_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
int ret = 0;
|
||||
struct profiler_dev_handle *data;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
file->private_data = data;
|
||||
data->abort = 0;
|
||||
data->released = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int compat_get_profiler_bw_info(
|
||||
struct compat_profiler_bw_cntrs_req __user *data32,
|
||||
struct profiler_bw_cntrs_req __user *data)
|
||||
{
|
||||
compat_uint_t val = 0;
|
||||
int err = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < (sizeof(struct profiler_bw_cntrs_req))
|
||||
/sizeof(uint32_t) - 1; ++i) {
|
||||
err |= get_user(val, (compat_uint_t *)data32 + i);
|
||||
err |= put_user(val, (uint32_t *)data + i);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int compat_put_profiler_bw_info(
|
||||
struct compat_profiler_bw_cntrs_req __user *data32,
|
||||
struct profiler_bw_cntrs_req __user *data)
|
||||
{
|
||||
compat_uint_t val = 0;
|
||||
int err = 0;
|
||||
int i = 0;
|
||||
|
||||
for (i = 0; i < (sizeof(struct profiler_bw_cntrs_req))
|
||||
/sizeof(uint32_t) - 1; ++i) {
|
||||
err |= get_user(val, (uint32_t *)data + i);
|
||||
err |= put_user(val, (compat_uint_t *)data32 + i);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static unsigned int convert_cmd(unsigned int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
case COMPAT_PROFILER_IOCTL_GET_BW_INFO:
|
||||
return PROFILER_IOCTL_GET_BW_INFO;
|
||||
|
||||
default:
|
||||
return cmd;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static long profiler_ioctl(struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
int ret = 0;
|
||||
struct profiler_dev_handle *data = file->private_data;
|
||||
void __user *argp = (void __user *) arg;
|
||||
|
||||
if (!data) {
|
||||
pr_err("Invalid/uninitialized device handle\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (data->abort) {
|
||||
pr_err("Aborting profiler driver\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case PROFILER_IOCTL_GET_BW_INFO:
|
||||
ret = profiler_get_bw_info(argp);
|
||||
if (ret)
|
||||
pr_err("failed get system bandwidth info: %d\n", ret);
|
||||
break;
|
||||
default:
|
||||
pr_err("Invalid IOCTL: 0x%x\n", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int profiler_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
pr_info("profiler release\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations profiler_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.unlocked_ioctl = profiler_ioctl,
|
||||
.open = profiler_open,
|
||||
.release = profiler_release
|
||||
};
|
||||
|
||||
static int profiler_init(void)
|
||||
{
|
||||
int rc;
|
||||
struct device *class_dev;
|
||||
|
||||
rc = alloc_chrdev_region(&profiler_device_no, 0, 1, PROFILER_DEV);
|
||||
if (rc < 0) {
|
||||
pr_err("alloc_chrdev_region failed %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
driver_class = class_create(THIS_MODULE, PROFILER_DEV);
|
||||
if (IS_ERR(driver_class)) {
|
||||
rc = -ENOMEM;
|
||||
pr_err("class_create failed %d\n", rc);
|
||||
goto exit_unreg_chrdev_region;
|
||||
}
|
||||
|
||||
class_dev = device_create(driver_class, NULL, profiler_device_no, NULL,
|
||||
PROFILER_DEV);
|
||||
if (IS_ERR(class_dev)) {
|
||||
pr_err("class_device_create failed %d\n", rc);
|
||||
rc = -ENOMEM;
|
||||
goto exit_destroy_class;
|
||||
}
|
||||
|
||||
cdev_init(&profiler.cdev, &profiler_fops);
|
||||
profiler.cdev.owner = THIS_MODULE;
|
||||
|
||||
rc = cdev_add(&profiler.cdev, MKDEV(MAJOR(profiler_device_no), 0), 1);
|
||||
if (rc < 0) {
|
||||
pr_err("%s: cdev_add failed %d\n", __func__, rc);
|
||||
goto exit_destroy_device;
|
||||
}
|
||||
|
||||
profiler.pdev = class_dev;
|
||||
return 0;
|
||||
|
||||
exit_destroy_device:
|
||||
device_destroy(driver_class, profiler_device_no);
|
||||
exit_destroy_class:
|
||||
class_destroy(driver_class);
|
||||
exit_unreg_chrdev_region:
|
||||
unregister_chrdev_region(profiler_device_no, 1);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void profiler_exit(void)
|
||||
{
|
||||
pr_info("Exiting from profiler\n");
|
||||
}
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. trustzone Communicator");
|
||||
|
||||
module_init(profiler_init);
|
||||
module_exit(profiler_exit);
|
@ -205,6 +205,8 @@ extern int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
|
||||
unsigned int *data);
|
||||
extern bool qcom_scm_is_available(void);
|
||||
extern int qcom_scm_mem_protect_audio(phys_addr_t paddr, size_t size);
|
||||
extern int qcom_scm_ddrbw_profiler(phys_addr_t in_buf, size_t in_buf_size,
|
||||
phys_addr_t out_buf, size_t out_buf_size);
|
||||
#else
|
||||
|
||||
#include <linux/errno.h>
|
||||
@ -390,5 +392,8 @@ static inline int qcom_scm_invoke_callback_response(phys_addr_t out_buf,
|
||||
static inline bool qcom_scm_is_available(void) { return false; }
|
||||
static inline int qcom_scm_mem_protect_audio(phys_addr_t paddr, size_t size)
|
||||
{ return -ENODEV; }
|
||||
static inline int qcom_scm_ddrbw_profiler(phys_addr_t in_buf, size_t in_buf_size,
|
||||
phys_addr_t out_buf, size_t out_buf_size)
|
||||
{ return -ENODEV; }
|
||||
#endif
|
||||
#endif
|
||||
|
96
include/soc/qcom/profiler.h
Normal file
96
include/soc/qcom/profiler.h
Normal file
@ -0,0 +1,96 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017, 2020-2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __PROFILER_H_
|
||||
#define __PROFILER_H_
|
||||
|
||||
|
||||
struct profiler_bw_cntrs_req {
|
||||
uint32_t llcc_total;
|
||||
uint32_t llcc_rd;
|
||||
uint32_t llcc_wr;
|
||||
uint32_t cabo_total;
|
||||
uint32_t cabo_rd;
|
||||
uint32_t cabo_wr;
|
||||
uint32_t cmd;
|
||||
};
|
||||
|
||||
struct compat_profiler_bw_cntrs_req {
|
||||
compat_uint_t llcc_total;
|
||||
compat_uint_t llcc_rd;
|
||||
compat_uint_t llcc_wr;
|
||||
compat_uint_t cabo_total;
|
||||
compat_uint_t cabo_rd;
|
||||
compat_uint_t cabo_wr;
|
||||
compat_uint_t cmd;
|
||||
};
|
||||
|
||||
/* Error types */
|
||||
enum tz_bw_svc_err {
|
||||
E_BW_SUCCESS = 0, /* Operation successful */
|
||||
E_BW_FAILURE = 1, /* Operation failed due to unknown err */
|
||||
E_BW_NULL_PARAM = 2, /* Null Parameter */
|
||||
E_BW_INVALID_ARG = 3, /* Arg is not recognized */
|
||||
E_BW_BAD_ADDRESS = 4, /* Ptr arg is bad address */
|
||||
E_BW_INVALID_ARG_LEN = 5, /* Arg length is wrong */
|
||||
E_BW_NOT_SUPPORTED = 6, /* Operation not supported */
|
||||
E_BW_NOT_PERMITTED = 7, /* Operation not permitted on platform */
|
||||
E_BW_TIME_LOCKED = 8, /* Operation not permitted right now */
|
||||
E_BW_RESERVED = 0x7FFFFFFF
|
||||
};
|
||||
|
||||
#define TZ_BW_SVC_VERSION (1)
|
||||
#define PROFILER_IOC_MAGIC 0x98
|
||||
|
||||
#define PROFILER_IOCTL_GET_BW_INFO \
|
||||
_IOWR(PROFILER_IOC_MAGIC, 1, struct profiler_bw_cntrs_req)
|
||||
|
||||
#define COMPAT_PROFILER_IOCTL_GET_BW_INFO \
|
||||
_IOWR(PROFILER_IOC_MAGIC, 1, struct compat_profiler_bw_cntrs_req)
|
||||
|
||||
/* Command types */
|
||||
enum tz_bw_svc_cmd {
|
||||
TZ_BW_SVC_START_ID = 0x00000001,
|
||||
TZ_BW_SVC_GET_ID = 0x00000002,
|
||||
TZ_BW_SVC_STOP_ID = 0x00000003,
|
||||
TZ_BW_SVC_LAST_ID = 0x7FFFFFFF
|
||||
};
|
||||
/* Start Request */
|
||||
struct tz_bw_svc_start_req {
|
||||
enum tz_bw_svc_cmd cmd_id;
|
||||
uint32_t version;
|
||||
} __packed;
|
||||
|
||||
/* Get Request */
|
||||
struct tz_bw_svc_get_req {
|
||||
enum tz_bw_svc_cmd cmd_id;
|
||||
uint64_t buf_ptr;
|
||||
uint32_t buf_size;
|
||||
} __packed;
|
||||
|
||||
/* Stop Request */
|
||||
struct tz_bw_svc_stop_req {
|
||||
enum tz_bw_svc_cmd cmd_id;
|
||||
} __packed;
|
||||
|
||||
struct tz_bw_svc_resp {
|
||||
enum tz_bw_svc_cmd cmd_id;
|
||||
enum tz_bw_svc_err status;
|
||||
} __packed;
|
||||
|
||||
union tz_bw_svc_req {
|
||||
struct tz_bw_svc_start_req start_req;
|
||||
struct tz_bw_svc_get_req get_req;
|
||||
struct tz_bw_svc_stop_req stop_req;
|
||||
} __packed;
|
||||
|
||||
struct tz_bw_svc_buf {
|
||||
union tz_bw_svc_req bwreq;
|
||||
struct tz_bw_svc_resp bwresp;
|
||||
uint32_t req_size;
|
||||
} __packed;
|
||||
|
||||
|
||||
#endif /* __PROFILER_H_ */
|
Loading…
Reference in New Issue
Block a user