00aa6e65aa
Multiple threads or clients can submit a command to the TEE ring
buffer. This patch helps to synchronize command submission to the
ring.
One thread shall write a command to a TEE ring buffer entry only if:
- Trusted OS has notified that the TEE command for the given entry
has been processed and driver has copied the TEE response into
client buffer.
- The command entry is empty and can be written into.
After a command has been written to the TEE ring buffer, the global
wptr (mutex protected) shall be incremented for use by next client.
If PSP became unresponsive while processing TEE request from a
client, then further command submission to queue will be disabled.
Fixes: 33960acccf
(crypto: ccp - add TEE support for Raven Ridge)
Reviewed-by: Devaraj Rangasamy <Devaraj.Rangasamy@amd.com>
Signed-off-by: Rijo Thomas <Rijo-john.Thomas@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
127 lines
3.3 KiB
C
127 lines
3.3 KiB
C
/* SPDX-License-Identifier: MIT */
|
|
/*
|
|
* Copyright (C) 2019,2021 Advanced Micro Devices, Inc.
|
|
*
|
|
* Author: Rijo Thomas <Rijo-john.Thomas@amd.com>
|
|
* Author: Devaraj Rangasamy <Devaraj.Rangasamy@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 988
|
|
|
|
/**
|
|
* 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 {
|
|
struct mutex mutex; /* synchronizes access to ring buffer */
|
|
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,
|
|
};
|
|
|
|
/**
|
|
* enum cmd_resp_state - TEE command's response status maintained by driver
|
|
* @CMD_RESPONSE_INVALID: initial state when no command is written to ring
|
|
* @CMD_WAITING_FOR_RESPONSE: driver waiting for response from TEE
|
|
* @CMD_RESPONSE_TIMEDOUT: failed to get response from TEE
|
|
* @CMD_RESPONSE_COPIED: driver has copied response from TEE
|
|
*/
|
|
enum cmd_resp_state {
|
|
CMD_RESPONSE_INVALID,
|
|
CMD_WAITING_FOR_RESPONSE,
|
|
CMD_RESPONSE_TIMEDOUT,
|
|
CMD_RESPONSE_COPIED,
|
|
};
|
|
|
|
/**
|
|
* 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
|
|
* @flag: refers to &enum cmd_resp_state
|
|
*/
|
|
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];
|
|
u32 flag;
|
|
|
|
/* 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__ */
|