1
0
mirror of https://github.com/physwizz/a155-U-u1.git synced 2024-11-19 13:27:49 +00:00
a155-U-u1/kernel-5.10/drivers/misc/mediatek/trusted_mem/tests/ut_ssheap.c
2024-03-11 06:53:12 +11:00

211 lines
4.9 KiB
C

// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2021 MediaTek Inc.
*/
#define pr_fmt(fmt) "[TMEM] ssheap ut: " fmt
#include <linux/types.h>
#include <linux/of_reserved_mem.h>
#include <linux/printk.h>
#include <linux/cma.h>
#include <linux/debugfs.h>
#include <linux/mutex.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/proc_fs.h>
#include <linux/uaccess.h>
#include <linux/memblock.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/sizes.h>
#include <linux/dma-direct.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/arm-smccc.h>
#include <linux/parser.h>
#include <public/trusted_mem_api.h>
#include <private/ssheap_priv.h>
enum {
UT_OPT_ERR = 0,
UT_OPT_CMD = 1 << 0,
UT_OPT_SIZE = 1 << 1,
UT_OPT_ALIGN = 1 << 2,
UT_OPT_DUMP = 1 << 3,
};
static const match_table_t opt_tokens = { { UT_OPT_CMD, "cmd=%d" },
{ UT_OPT_SIZE, "size=%x" },
{ UT_OPT_ALIGN, "align=%x" },
{ UT_OPT_DUMP, "dump=%d" },
{ UT_OPT_ERR, NULL } };
static int ssheap_open(__always_unused struct inode *inode,
__always_unused struct file *file)
{
pr_info("%s:%d\n", __func__, __LINE__);
return 0;
}
static int ssheap_release(__always_unused struct inode *ino,
__always_unused struct file *file)
{
pr_info("%s:%d\n", __func__, __LINE__);
return 0;
}
static void dump_buf_info(struct ssheap_buf_info *info)
{
int i;
struct scatterlist *sg;
uint64_t dma_addr;
pr_info("%s: info:%p", __func__, info);
pr_info("%s: table=%p", __func__, info->table);
pr_info("%s: alignment: 0x%lx", __func__, info->alignment);
pr_info("%s: req_size: 0x%lx", __func__, info->req_size);
pr_info("%s: aligned_req_size: 0x%lx", __func__,
info->aligned_req_size);
pr_info("%s: allocated_size: 0x%lx", __func__, info->allocated_size);
pr_info("%s: elemts: %ld", __func__, info->elems);
if (info->table) {
for_each_sg(info->table->sgl, sg, info->table->nents, i) {
dma_addr = sg_dma_address(sg);
pr_info("%s: sg idx:%d dma_addr=%llx size=%x\n",
__func__, i, dma_addr, sg->length);
}
}
}
static void ssheap_ut(const char *buf)
{
struct ssheap_buf_info *info;
static struct ssheap_buf_info *last_info;
int token;
substring_t args[MAX_OPT_ARGS];
uint32_t ut_cmd = 0;
uint32_t ut_size = 0;
uint32_t ut_align = 0;
uint32_t ut_dump = 0;
char *options, *p, *o;
unsigned long smc_ret;
options = o = kstrdup(buf, GFP_KERNEL);
while ((p = strsep(&o, " \t\n")) != NULL) {
if (!*p)
continue;
pr_info("args: %s\n", p);
token = match_token(p, opt_tokens, args);
switch (token) {
case UT_OPT_CMD:
if (match_int(args, &token))
break;
ut_cmd = token;
break;
case UT_OPT_SIZE:
if (match_hex(args, &token))
break;
ut_size = token;
break;
case UT_OPT_ALIGN:
if (match_hex(args, &token))
break;
ut_align = token;
break;
case UT_OPT_DUMP:
if (match_hex(args, &token))
break;
ut_dump = token;
break;
default:
break;
}
}
pr_info("cmd=%d size=%#x align=%#x\n", ut_cmd, ut_size, ut_align);
if (ut_cmd == 1) {
info = ssheap_alloc_non_contig(ut_size, ut_align, 0x9);
if (info == NULL) {
pr_info("cmd=%d FAILED\n", ut_cmd);
} else {
smc_ret = mtee_assign_buffer(info, 0x9);
pr_debug("secure buffer ret:%d (0x%x)\n", smc_ret,
smc_ret);
smc_ret = mtee_unassign_buffer(info, 0x9);
pr_debug("unsecure buffer ret:%d (0x%x)\n", smc_ret,
smc_ret);
if (ut_dump)
dump_buf_info(info);
ssheap_free_non_contig(info);
pr_info("cmd=%d PASSED\n", ut_cmd);
}
}
if (ut_cmd == 11) {
if (last_info) {
pr_info("cmd=%d FAILED (last_info should be NULL)\n",
ut_cmd);
goto out;
}
last_info = ssheap_alloc_non_contig(ut_size, ut_align, 0xff);
if (last_info == NULL) {
pr_info("cmd=%d FAILED\n", ut_cmd);
} else {
smc_ret = mtee_assign_buffer(last_info, 0xff);
pr_info("secure buffer ret:%d (0x%x)\n", smc_ret,
smc_ret);
if (ut_dump)
dump_buf_info(last_info);
pr_info("cmd=%d PASSED\n", ut_cmd);
}
}
if (ut_cmd == 12) {
if (last_info == NULL) {
pr_info("last_info is NULL\n");
pr_info("cmd=%d FAILED\n", ut_cmd);
goto out;
}
smc_ret = mtee_unassign_buffer(last_info, 0xff);
pr_info("unsecure buffer ret:%d (0x%x)\n", smc_ret, smc_ret);
ssheap_free_non_contig(last_info);
last_info = NULL;
pr_info("cmd=%d PASSED\n", ut_cmd);
}
out:
if (ut_dump)
ssheap_dump_mem_info();
kfree(options);
}
static ssize_t ssheap_write(struct file *file, const char __user *buffer,
size_t count, loff_t *data)
{
char desc[128];
if (copy_from_user(desc, buffer, count))
return 0;
pr_info("write count:%d\n", count);
ssheap_ut(desc);
return count;
}
static const struct proc_ops ssheap_fops = {
.proc_open = ssheap_open,
.proc_release = ssheap_release,
.proc_ioctl = NULL,
.proc_write = ssheap_write,
};
void create_ssheap_ut_device(void)
{
proc_create("ssheap0", 0664, NULL, &ssheap_fops);
}