Re: [RFC PATCH 4/5] crypto: ccp - add TEE support for Raven Ridge

Thomas, Rijo-john
2019-10-24T11:20:45Z

Hello Ard,

On 23/10/19 5:19 PM, Ard Biesheuvel wrote:
> (+ Jens)
>
> On Wed, 23 Oct 2019 at 13:27, Thomas, Rijo-john
> <Rijo-john.Thomas@amd.com> wrote:
>>
>> Adds a PCI device entry for Raven Ridge. Raven Ridge is an APU with a
>> dedicated AMD Secure Processor having Trusted Execution Environment (TEE)
>> support. The TEE provides a secure environment for running Trusted
>> Applications (TAs) which implement security-sensitive parts of a feature.
>>
>> This patch configures AMD Secure Processor's TEE interface by initializing
>> a ring buffer (shared memory between Rich OS and Trusted OS) which can hold
>> multiple command buffer entries. The TEE interface is facilitated by a set
>> of CPU to PSP mailbox registers.
>>
>> The next patch will address how commands are submitted to the ring buffer.
>>
>> Signed-off-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
>> Signed-off-by: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
>> ---
>> drivers/crypto/ccp/Makefile | 3 +-
>> drivers/crypto/ccp/psp-dev.c | 74 +++++++++++++-
>> drivers/crypto/ccp/psp-dev.h | 8 ++
>> drivers/crypto/ccp/sp-dev.h | 11 +-
>> drivers/crypto/ccp/sp-pci.c | 27 ++++-
>> drivers/crypto/ccp/tee-dev.c | 237 +++++++++++++++++++++++++++++++++++++++++++
>> drivers/crypto/ccp/tee-dev.h | 108 ++++++++++++++++++++
>> 7 files changed, 461 insertions(+), 7 deletions(-)
>> create mode 100644 drivers/crypto/ccp/tee-dev.c
>> create mode 100644 drivers/crypto/ccp/tee-dev.h
>>
>
> How does this patch tie into the TEE subsystem we have in drivers/tee?
>
>

In the next patch in this series:

crypto: ccp - provide in-kernel API to submit TEE commands

Link : https://patchwork.kernel.org/patch/11206441/

we introduce an API psp_tee_process_cmd(), which will be called by AMD-TEE
driver. The AMD-TEE drivers registers itself with the TEE subsystem and uses
psp_tee_process_cmd() to submit command buffers for processing by Trusted OS
running on AMD Secure Processor.

The AMD-TEE driver is introduced as a separate patchset and can be found here:
https://lkml.org/lkml/2019/10/23/457

Thanks,
Rijo

>
>
>> diff --git a/drivers/crypto/ccp/Makefile b/drivers/crypto/ccp/Makefile
>> index 3b29ea4..db362fe 100644
>> --- a/drivers/crypto/ccp/Makefile
>> +++ b/drivers/crypto/ccp/Makefile
>> @@ -9,7 +9,8 @@ ccp-$(CONFIG_CRYPTO_DEV_SP_CCP) += ccp-dev.o \
>> ccp-$(CONFIG_CRYPTO_DEV_CCP_DEBUGFS) += ccp-debugfs.o
>> ccp-$(CONFIG_PCI) += sp-pci.o
>> ccp-$(CONFIG_CRYPTO_DEV_SP_PSP) += psp-dev.o \
>> - sev-dev.o
>> + sev-dev.o \
>> + tee-dev.o
>>
>> obj-$(CONFIG_CRYPTO_DEV_CCP_CRYPTO) += ccp-crypto.o
>> ccp-crypto-objs := ccp-crypto-main.o \
>> diff --git a/drivers/crypto/ccp/psp-dev.c b/drivers/crypto/ccp/psp-dev.c
>> index ef8affa..90bcd5f 100644
>> --- a/drivers/crypto/ccp/psp-dev.c
>> +++ b/drivers/crypto/ccp/psp-dev.c
>> @@ -13,6 +13,7 @@
>> #include "sp-dev.h"
>> #include "psp-dev.h"
>> #include "sev-dev.h"
>> +#include "tee-dev.h"
>>
>> struct psp_device *psp_master;
>>
>> @@ -45,6 +46,9 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
>> if (status) {
>> if (psp->sev_irq_handler)
>> psp->sev_irq_handler(irq, psp->sev_irq_data, status);
>> +
>> + if (psp->tee_irq_handler)
>> + psp->tee_irq_handler(irq, psp->tee_irq_data, status);
>> }
>>
>> /* Clear the interrupt status by writing the same value we read. */
>> @@ -53,10 +57,11 @@ static irqreturn_t psp_irq_handler(int irq, void *data)
>> return IRQ_HANDLED;
>> }
>>
>> -static int psp_check_sev_support(struct psp_device *psp)
>> +static int psp_check_sev_support(struct psp_device *psp,
>> + unsigned int capability)
>> {
>> /* Check if device supports SEV feature */
>> - if (!(ioread32(psp->io_regs + psp->vdata->feature_reg) & 1)) {
>> + if (!(capability & 1)) {
>> dev_dbg(psp->dev, "psp does not support SEV\n");
>> return -ENODEV;
>> }
>> @@ -64,10 +69,54 @@ static int psp_check_sev_support(struct psp_device *psp)
>> return 0;
>> }
>>
>> +static int psp_check_tee_support(struct psp_device *psp,
>> + unsigned int capability)
>> +{
>> + /* Check if device supports TEE feature */
>> + if (!(capability & 2)) {
>> + dev_dbg(psp->dev, "psp does not support TEE\n");
>> + return -ENODEV;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> +static int psp_check_support(struct psp_device *psp, unsigned int capability)
>> +{
>> + int sev_support = psp_check_sev_support(psp, capability);
>> + int tee_support = psp_check_tee_support(psp, capability);
>> +
>> + /* Check if device supprts SEV and TEE feature */
>> + if (sev_support && tee_support)
>> + return -ENODEV;
>> +
>> + return 0;
>> +}
>> +
>> +static int psp_init(struct psp_device *psp, unsigned int capability)
>> +{
>> + int ret;
>> +
>> + if (!psp_check_sev_support(psp, capability)) {
>> + ret = sev_dev_init(psp);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + if (!psp_check_tee_support(psp, capability)) {
>> + ret = tee_dev_init(psp);
>> + if (ret)
>> + return ret;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> int psp_dev_init(struct sp_device *sp)
>> {
>> struct device *dev = sp->dev;
>> struct psp_device *psp;
>> + unsigned int capability;
>> int ret;
>>
>> ret = -ENOMEM;
>> @@ -86,7 +135,10 @@ int psp_dev_init(struct sp_device *sp)
>>
>> psp->io_regs = sp->io_map;
>>
>> - ret = psp_check_sev_support(psp);
>> + /* Read the feature register to get the PSP capability */
>> + capability = ioread32(psp->io_regs + psp->vdata->feature_reg);
>> +
>> + ret = psp_check_support(psp, capability);
>> if (ret)
>> goto e_disable;
>>
>> @@ -101,7 +153,7 @@ int psp_dev_init(struct sp_device *sp)
>> goto e_err;
>> }
>>
>> - ret = sev_dev_init(psp);
>> + ret = psp_init(psp, capability);
>> if (ret)
>> goto e_irq;
>>
>> @@ -139,6 +191,8 @@ void psp_dev_destroy(struct sp_device *sp)
>>
>> sev_dev_destroy(psp);
>>
>> + tee_dev_destroy(psp);
>> +
>> sp_free_psp_irq(sp, psp);
>> }
>>
>> @@ -154,6 +208,18 @@ void psp_clear_sev_irq_handler(struct psp_device *psp)
>> psp_set_sev_irq_handler(psp, NULL, NULL);
>> }
>>
>> +void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
>> + void *data)
>> +{
>> + psp->tee_irq_data = data;
>> + psp->tee_irq_handler = handler;
>> +}
>> +
>> +void psp_clear_tee_irq_handler(struct psp_device *psp)
>> +{
>> + psp_set_tee_irq_handler(psp, NULL, NULL);
>> +}
>> +
>> struct psp_device *psp_get_master_device(void)
>> {
>> struct sp_device *sp = sp_get_psp_master_device();
>> diff --git a/drivers/crypto/ccp/psp-dev.h b/drivers/crypto/ccp/psp-dev.h
>> index 7c014ac..ef38e41 100644
>> --- a/drivers/crypto/ccp/psp-dev.h
>> +++ b/drivers/crypto/ccp/psp-dev.h
>> @@ -40,13 +40,21 @@ struct psp_device {
>> psp_irq_handler_t sev_irq_handler;
>> void *sev_irq_data;
>>
>> + psp_irq_handler_t tee_irq_handler;
>> + void *tee_irq_data;
>> +
>> void *sev_data;
>> + void *tee_data;
>> };
>>
>> void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
>> void *data);
>> void psp_clear_sev_irq_handler(struct psp_device *psp);
>>
>> +void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
>> + void *data);
>> +void psp_clear_tee_irq_handler(struct psp_device *psp);
>> +
>> struct psp_device *psp_get_master_device(void);
>>
>> #endif /* __PSP_DEV_H */
>> diff --git a/drivers/crypto/ccp/sp-dev.h b/drivers/crypto/ccp/sp-dev.h
>> index 0394c75..4235946 100644
>> --- a/drivers/crypto/ccp/sp-dev.h
>> +++ b/drivers/crypto/ccp/sp-dev.h
>> @@ -2,7 +2,7 @@
>> /*
>> * AMD Secure Processor driver
>> *
>> - * Copyright (C) 2017-2018 Advanced Micro Devices, Inc.
>> + * Copyright (C) 2017-2019 Advanced Micro Devices, Inc.
>> *
>> * Author: Tom Lendacky <thomas.lendacky@amd.com>
>> * Author: Gary R Hook <gary.hook@amd.com>
>> @@ -45,8 +45,17 @@ struct sev_vdata {
>> const unsigned int cmdbuff_addr_hi_reg;
>> };
>>
>> +struct tee_vdata {
>> + const unsigned int cmdresp_reg;
>> + const unsigned int cmdbuff_addr_lo_reg;
>> + const unsigned int cmdbuff_addr_hi_reg;
>> + const unsigned int ring_wptr_reg;
>> + const unsigned int ring_rptr_reg;
>> +};
>> +
>> struct psp_vdata {
>> const struct sev_vdata *sev;
>> + const struct tee_vdata *tee;
>> const unsigned int feature_reg;
>> const unsigned int inten_reg;
>> const unsigned int intsts_reg;
>> diff --git a/drivers/crypto/ccp/sp-pci.c b/drivers/crypto/ccp/sp-pci.c
>> index 733693d..56c1f61 100644
>> --- a/drivers/crypto/ccp/sp-pci.c
>> +++ b/drivers/crypto/ccp/sp-pci.c
>> @@ -2,7 +2,7 @@
>> /*
>> * AMD Secure Processor device driver
>> *
>> - * Copyright (C) 2013,2018 Advanced Micro Devices, Inc.
>> + * Copyright (C) 2013,2019 Advanced Micro Devices, Inc.
>> *
>> * Author: Tom Lendacky <thomas.lendacky@amd.com>
>> * Author: Gary R Hook <gary.hook@amd.com>
>> @@ -274,6 +274,14 @@ static int sp_pci_resume(struct pci_dev *pdev)
>> .cmdbuff_addr_hi_reg = 0x109e4,
>> };
>>
>> +static const struct tee_vdata teev1 = {
>> + .cmdresp_reg = 0x10544,
>> + .cmdbuff_addr_lo_reg = 0x10548,
>> + .cmdbuff_addr_hi_reg = 0x1054c,
>> + .ring_wptr_reg = 0x10550,
>> + .ring_rptr_reg = 0x10554,
>> +};
>> +
>> static const struct psp_vdata pspv1 = {
>> .sev = &sevv1,
>> .feature_reg = 0x105fc,
>> @@ -287,6 +295,13 @@ static int sp_pci_resume(struct pci_dev *pdev)
>> .inten_reg = 0x10690,
>> .intsts_reg = 0x10694,
>> };
>> +
>> +static const struct psp_vdata pspv3 = {
>> + .tee = &teev1,
>> + .feature_reg = 0x109fc,
>> + .inten_reg = 0x10690,
>> + .intsts_reg = 0x10694,
>> +};
>> #endif
>>
>> static const struct sp_dev_vdata dev_vdata[] = {
>> @@ -320,12 +335,22 @@ static int sp_pci_resume(struct pci_dev *pdev)
>> .psp_vdata = &pspv2,
>> #endif
>> },
>> + { /* 4 */
>> + .bar = 2,
>> +#ifdef CONFIG_CRYPTO_DEV_SP_CCP
>> + .ccp_vdata = &ccpv5a,
>> +#endif
>> +#ifdef CONFIG_CRYPTO_DEV_SP_PSP
>> + .psp_vdata = &pspv3,
>> +#endif
>> + },
>> };
>> static const struct pci_device_id sp_pci_table[] = {
>> { PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
>> { PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
>> { PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
>> { PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] },
>> + { PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] },
>> /* Last entry must be zero */
>> { 0, }
>> };
>> diff --git a/drivers/crypto/ccp/tee-dev.c b/drivers/crypto/ccp/tee-dev.c
>> new file mode 100644
>> index 0000000..b2b0215
>> --- /dev/null
>> +++ b/drivers/crypto/ccp/tee-dev.c
>> @@ -0,0 +1,237 @@
>> +// SPDX-License-Identifier: MIT
>> +/*
>> + * AMD Trusted Execution Environment (TEE) interface
>> + *
>> + * Author: Rijo Thomas <Rijo-john.Thomas@amd.com>
>> + *
>> + * Copyright 2019 Advanced Micro Devices, Inc.
>> + */
>> +
>> +#include <linux/types.h>
>> +#include <linux/mutex.h>
>> +#include <linux/delay.h>
>> +#include <linux/slab.h>
>> +#include <linux/gfp.h>
>> +#include <linux/psp-sev.h>
>> +
>> +#include "psp-dev.h"
>> +#include "tee-dev.h"
>> +
>> +static bool psp_dead;
>> +
>> +static int tee_alloc_ring(struct psp_tee_device *tee, int ring_size)
>> +{
>> + struct ring_buf_manager *rb_mgr = &tee->rb_mgr;
>> + void *start_addr;
>> +
>> + if (!ring_size)
>> + return -EINVAL;
>> +
>> + /* We need actual physical address instead of DMA address, since
>> + * Trusted OS running on AMD Secure Processor will map this region
>> + */
>> + start_addr = (void *)__get_free_pages(GFP_KERNEL, get_order(ring_size));
>> + if (!start_addr)
>> + return -ENOMEM;
>> +
>> + rb_mgr->ring_start = start_addr;
>> + rb_mgr->ring_size = ring_size;
>> + rb_mgr->ring_pa = __psp_pa(start_addr);
>> +
>> + return 0;
>> +}
>> +
>> +static void tee_free_ring(struct psp_tee_device *tee)
>> +{
>> + struct ring_buf_manager *rb_mgr = &tee->rb_mgr;
>> +
>> + if (!rb_mgr->ring_start)
>> + return;
>> +
>> + free_pages((unsigned long)rb_mgr->ring_start,
>> + get_order(rb_mgr->ring_size));
>> +
>> + rb_mgr->ring_start = NULL;
>> + rb_mgr->ring_size = 0;
>> + rb_mgr->ring_pa = 0;
>> +}
>> +
>> +static int tee_wait_cmd_poll(struct psp_tee_device *tee, unsigned int timeout,
>> + unsigned int *reg)
>> +{
>> + /* ~10ms sleep per loop => nloop = timeout * 100 */
>> + int nloop = timeout * 100;
>> +
>> + while (--nloop) {
>> + *reg = ioread32(tee->io_regs + tee->vdata->cmdresp_reg);
>> + if (*reg & PSP_CMDRESP_RESP)
>> + return 0;
>> +
>> + usleep_range(10000, 10100);
>> + }
>> +
>> + dev_err(tee->dev, "tee: command timed out, disabling PSP\n");
>> + psp_dead = true;
>> +
>> + return -ETIMEDOUT;
>> +}
>> +
>> +static
>> +struct tee_init_ring_cmd *tee_alloc_cmd_buffer(struct psp_tee_device *tee)
>> +{
>> + struct tee_init_ring_cmd *cmd;
>> +
>> + cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
>> + if (!cmd)
>> + return NULL;
>> +
>> + cmd->hi_addr = upper_32_bits(tee->rb_mgr.ring_pa);
>> + cmd->low_addr = lower_32_bits(tee->rb_mgr.ring_pa);
>> + cmd->size = tee->rb_mgr.ring_size;
>> +
>> + dev_dbg(tee->dev, "tee: ring address: high = 0x%x low = 0x%x size = %u\n",
>> + cmd->hi_addr, cmd->low_addr, cmd->size);
>> +
>> + return cmd;
>> +}
>> +
>> +static inline void tee_free_cmd_buffer(struct tee_init_ring_cmd *cmd)
>> +{
>> + kfree(cmd);
>> +}
>> +
>> +static int tee_init_ring(struct psp_tee_device *tee)
>> +{
>> + int ring_size = MAX_RING_BUFFER_ENTRIES * sizeof(struct tee_ring_cmd);
>> + struct tee_init_ring_cmd *cmd;
>> + phys_addr_t cmd_buffer;
>> + unsigned int reg;
>> + int ret;
>> +
>> + BUILD_BUG_ON(sizeof(struct tee_ring_cmd) != 1024);
>> +
>> + ret = tee_alloc_ring(tee, ring_size);
>> + if (ret) {
>> + dev_err(tee->dev, "tee: ring allocation failed %d\n", ret);
>> + return ret;
>> + }
>> +
>> + tee->rb_mgr.wptr = 0;
>> +
>> + cmd = tee_alloc_cmd_buffer(tee);
>> + if (!cmd) {
>> + tee_free_ring(tee);
>> + return -ENOMEM;
>> + }
>> +
>> + cmd_buffer = __psp_pa((void *)cmd);
>> +
>> + /* Send command buffer details to Trusted OS by writing to
>> + * CPU-PSP message registers
>> + */
>> +
>> + iowrite32(lower_32_bits(cmd_buffer),
>> + tee->io_regs + tee->vdata->cmdbuff_addr_lo_reg);
>> + iowrite32(upper_32_bits(cmd_buffer),
>> + tee->io_regs + tee->vdata->cmdbuff_addr_hi_reg);
>> + iowrite32(TEE_RING_INIT_CMD,
>> + tee->io_regs + tee->vdata->cmdresp_reg);
>> +
>> + ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg);
>> + if (ret) {
>> + dev_err(tee->dev, "tee: ring init command timed out\n");
>> + tee_free_ring(tee);
>> + goto free_buf;
>> + }
>> +
>> + if (reg & PSP_CMDRESP_ERR_MASK) {
>> + dev_err(tee->dev, "tee: ring init command failed (%#010x)\n",
>> + reg & PSP_CMDRESP_ERR_MASK);
>> + tee_free_ring(tee);
>> + ret = -EIO;
>> + }
>> +
>> +free_buf:
>> + tee_free_cmd_buffer(cmd);
>> +
>> + return ret;
>> +}
>> +
>> +static void tee_destroy_ring(struct psp_tee_device *tee)
>> +{
>> + unsigned int reg;
>> + int ret;
>> +
>> + if (!tee->rb_mgr.ring_start)
>> + return;
>> +
>> + if (psp_dead)
>> + goto free_ring;
>> +
>> + iowrite32(TEE_RING_DESTROY_CMD,
>> + tee->io_regs + tee->vdata->cmdresp_reg);
>> +
>> + ret = tee_wait_cmd_poll(tee, TEE_DEFAULT_TIMEOUT, &reg);
>> + if (ret) {
>> + dev_err(tee->dev, "tee: ring destroy command timed out\n");
>> + } else if (reg & PSP_CMDRESP_ERR_MASK) {
>> + dev_err(tee->dev, "tee: ring destroy command failed (%#010x)\n",
>> + reg & PSP_CMDRESP_ERR_MASK);
>> + }
>> +
>> +free_ring:
>> + tee_free_ring(tee);
>> +}
>> +
>> +int tee_dev_init(struct psp_device *psp)
>> +{
>> + struct device *dev = psp->dev;
>> + struct psp_tee_device *tee;
>> + int ret;
>> +
>> + ret = -ENOMEM;
>> + tee = devm_kzalloc(dev, sizeof(*tee), GFP_KERNEL);
>> + if (!tee)
>> + goto e_err;
>> +
>> + psp->tee_data = tee;
>> +
>> + tee->dev = dev;
>> + tee->psp = psp;
>> +
>> + tee->io_regs = psp->io_regs;
>> +
>> + tee->vdata = (struct tee_vdata *)psp->vdata->tee;
>> + if (!tee->vdata) {
>> + ret = -ENODEV;
>> + dev_err(dev, "tee: missing driver data\n");
>> + goto e_err;
>> + }
>> +
>> + ret = tee_init_ring(tee);
>> + if (ret) {
>> + dev_err(dev, "tee: failed to init ring buffer\n");
>> + goto e_err;
>> + }
>> +
>> + dev_notice(dev, "tee enabled\n");
>> +
>> + return 0;
>> +
>> +e_err:
>> + psp->tee_data = NULL;
>> +
>> + dev_notice(dev, "tee initialization failed\n");
>> +
>> + return ret;
>> +}
>> +
>> +void tee_dev_destroy(struct psp_device *psp)
>> +{
>> + struct psp_tee_device *tee = psp->tee_data;
>> +
>> + if (!tee)
>> + return;
>> +
>> + tee_destroy_ring(tee);
>> +}
>> diff --git a/drivers/crypto/ccp/tee-dev.h b/drivers/crypto/ccp/tee-dev.h
>> new file mode 100644
>> index 0000000..0d51a0a7
>> --- /dev/null
>> +++ b/drivers/crypto/ccp/tee-dev.h
>> @@ -0,0 +1,108 @@
>> +/* SPDX-License-Identifier: MIT */
>> +/*
>> + * Copyright 2019 Advanced Micro Devices, Inc.
>> + *
>> + * Author: Rijo Thomas <Rijo-john.Thomas@amd.com>
>> + *
>> + */
>> +
>> +/* This file describes the TEE communication interface between host and AMD
>> + * Secure Processor
>> + */
>> +
>> +#ifndef __TEE_DEV_H__
>> +#define __TEE_DEV_H__
>> +
>> +#include <linux/device.h>
>> +#include <linux/mutex.h>
>> +
>> +#define TEE_DEFAULT_TIMEOUT 10
>> +#define MAX_BUFFER_SIZE 992
>> +
>> +/**
>> + * enum tee_ring_cmd_id - TEE interface commands for ring buffer configuration
>> + * @TEE_RING_INIT_CMD: Initialize ring buffer
>> + * @TEE_RING_DESTROY_CMD: Destroy ring buffer
>> + * @TEE_RING_MAX_CMD: Maximum command id
>> + */
>> +enum tee_ring_cmd_id {
>> + TEE_RING_INIT_CMD = 0x00010000,
>> + TEE_RING_DESTROY_CMD = 0x00020000,
>> + TEE_RING_MAX_CMD = 0x000F0000,
>> +};
>> +
>> +/**
>> + * struct tee_init_ring_cmd - Command to init TEE ring buffer
>> + * @low_addr: bits [31:0] of the physical address of ring buffer
>> + * @hi_addr: bits [63:32] of the physical address of ring buffer
>> + * @size: size of ring buffer in bytes
>> + */
>> +struct tee_init_ring_cmd {
>> + u32 low_addr;
>> + u32 hi_addr;
>> + u32 size;
>> +};
>> +
>> +#define MAX_RING_BUFFER_ENTRIES 32
>> +
>> +/**
>> + * struct ring_buf_manager - Helper structure to manage ring buffer.
>> + * @ring_start: starting address of ring buffer
>> + * @ring_size: size of ring buffer in bytes
>> + * @ring_pa: physical address of ring buffer
>> + * @wptr: index to the last written entry in ring buffer
>> + */
>> +struct ring_buf_manager {
>> + void *ring_start;
>> + u32 ring_size;
>> + phys_addr_t ring_pa;
>> + u32 wptr;
>> +};
>> +
>> +struct psp_tee_device {
>> + struct device *dev;
>> + struct psp_device *psp;
>> + void __iomem *io_regs;
>> + struct tee_vdata *vdata;
>> + struct ring_buf_manager rb_mgr;
>> +};
>> +
>> +/**
>> + * enum tee_cmd_state - TEE command states for the ring buffer interface
>> + * @TEE_CMD_STATE_INIT: initial state of command when sent from host
>> + * @TEE_CMD_STATE_PROCESS: command being processed by TEE environment
>> + * @TEE_CMD_STATE_COMPLETED: command processing completed
>> + */
>> +enum tee_cmd_state {
>> + TEE_CMD_STATE_INIT,
>> + TEE_CMD_STATE_PROCESS,
>> + TEE_CMD_STATE_COMPLETED,
>> +};
>> +
>> +/**
>> + * struct tee_ring_cmd - Structure of the command buffer in TEE ring
>> + * @cmd_id: refers to &enum tee_cmd_id. Command id for the ring buffer
>> + * interface
>> + * @cmd_state: refers to &enum tee_cmd_state
>> + * @status: status of TEE command execution
>> + * @res0: reserved region
>> + * @pdata: private data (currently unused)
>> + * @res1: reserved region
>> + * @buf: TEE command specific buffer
>> + */
>> +struct tee_ring_cmd {
>> + u32 cmd_id;
>> + u32 cmd_state;
>> + u32 status;
>> + u32 res0[1];
>> + u64 pdata;
>> + u32 res1[2];
>> + u8 buf[MAX_BUFFER_SIZE];
>> +
>> + /* Total size: 1024 bytes */
>> +} __packed;
>> +
>> +int tee_dev_init(struct psp_device *psp);
>> +void tee_dev_destroy(struct psp_device *psp);
>> +
>> +#endif /* __TEE_DEV_H__ */
>> --
>> 1.9.1
>>