You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

165 lines
4.3 KiB

/*
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2021. All rights reserved.
* Description:KS driver in register level.
* Author: Hisilicon
* Create: 2019/06/22
*/
#include "hal_keyslot.h"
#include "osal_ext.h"
#include "drv_keyslot_define.h"
#include "drv_keyslot_func.h"
#include "hal_keyslot_reg.h"
static td_void _ks_write_reg(const td_u32 addr, const td_u32 val)
{
struct ks_mgmt *mgmt = priv_get_ks_mgmt();
reg_write((mgmt->io_base + addr), val);
ext_info_ks("ks w 0x%08x 0x%08x\n", mgmt->reg.reg + addr, val);
return;
}
td_u32 _ks_read_reg(const td_u32 addr)
{
td_u32 val = 0;
struct ks_mgmt *mgmt = priv_get_ks_mgmt();
reg_read((mgmt->io_base + addr), val);
ext_info_ks("ks r 0x%08x 0x%08x\n", mgmt->reg.reg + addr, val);
return val;
}
static td_u32 _ks_get_flush_status(td_void)
{
#ifdef CONFIG_SOCT_TEE_SUPPORT
return _ks_read_reg(KC_REE_FLUSH_BUSY);
#else
return _ks_read_reg(KC_TEE_FLUSH_BUSY);
#endif
}
static td_bool _ks_is_busy(td_void)
{
/* bit 0 is 1 means there is a key slot flushed by the current cpu */
return ((_ks_get_flush_status() & 0x1) != 0x0) ? TD_TRUE : TD_FALSE;
}
static td_bool _ks_flush_failed(td_void)
{
/* bit 1 is 1 means current cpu flush the target key slot due to time out */
return ((_ks_get_flush_status() & 0x2) != 0x0) ? TD_TRUE : TD_FALSE;
}
#define LOOP_MAX 1000
#define DELAY_US 1
static td_s32 _ks_flush_wait(td_void)
{
td_u32 time_out = LOOP_MAX;
while (time_out--) {
if (_ks_is_busy() == TD_FALSE) {
break;
}
osal_udelay(DELAY_US);
}
if (time_out == 0) {
return SOC_ERR_KS_STAT_TIME_OUT;
}
if (_ks_flush_failed()) {
return SOC_ERR_KS_FLUSH_TIME_OUT;
}
return TD_SUCCESS;
}
static td_bool _ks_is_tscipher(const ext_keyslot_type slot_ind)
{
if (slot_ind == EXT_KEYSLOT_TYPE_TSCIPHER) {
return TD_TRUE;
} else {
return TD_FALSE;
}
}
ks_slot_stat hal_ks_status(const ext_keyslot_type slot_ind, const td_u32 slot_num)
{
kc_rd_lock_status stat;
kc_rd_slot_num slot;
slot.u32 = _ks_read_reg(KC_RD_SLOT_NUM);
slot.bits.tscipher_slot_ind = _ks_is_tscipher(slot_ind);
slot.bits.slot_num_cfg = slot_num;
_ks_write_reg(KC_RD_SLOT_NUM, slot.u32);
stat.u32 = _ks_read_reg(KC_RD_LOCK_STATUS);
return (ks_slot_stat)stat.bits.rd_lock_status;
}
td_s32 hal_ks_lock(const ext_keyslot_type slot_ind, const td_u32 slot_num)
{
ks_slot_stat state;
#ifdef CONFIG_SOCT_TEE_SUPPORT
kc_ree_lock_cmd ree_reg;
if (_ks_is_busy()) {
return SOC_ERR_KS_BUSY;
}
ree_reg.u32 = _ks_read_reg(KC_REE_LOCK_CMD);
ree_reg.bits.ree_lock_cmd = 1;
ree_reg.bits.ree_tscipher_ind = _ks_is_tscipher(slot_ind);
ree_reg.bits.ree_key_slot_num = slot_num;
_ks_write_reg(KC_REE_LOCK_CMD, ree_reg.u32);
state = hal_ks_status(slot_ind, slot_num);
if (state != KS_STAT_REE_LOCK) {
return SOC_ERR_KS_LOCKED_CPUX + state;
}
#else
kc_tee_lock_cmd tee_reg;
if (_ks_is_busy()) {
return SOC_ERR_KS_BUSY;
}
tee_reg.u32 = _ks_read_reg(KC_TEE_LOCK_CMD);
tee_reg.bits.tee_lock_cmd = 1;
tee_reg.bits.tpp_key_enable = 1;
tee_reg.bits.tee_tscipher_ind = _ks_is_tscipher(slot_ind);
tee_reg.bits.tee_key_slot_num = slot_num;
_ks_write_reg(KC_TEE_LOCK_CMD, tee_reg.u32);
state = hal_ks_status(slot_ind, slot_num);
if (state != KS_STAT_TEE_LOCK) {
return SOC_ERR_KS_LOCKED_CPUX + state;
}
#endif
return TD_SUCCESS;
}
td_s32 hal_ks_unlock(const ext_keyslot_type slot_ind, const td_u32 slot_num)
{
#ifdef CONFIG_SOCT_TEE_SUPPORT
kc_ree_lock_cmd ree_reg;
if (_ks_is_busy()) {
return SOC_ERR_KS_BUSY;
}
ree_reg.u32 = _ks_read_reg(KC_REE_LOCK_CMD);
ree_reg.bits.ree_lock_cmd = 0;
ree_reg.bits.ree_tscipher_ind = _ks_is_tscipher(slot_ind);
ree_reg.bits.ree_key_slot_num = slot_num;
_ks_write_reg(KC_REE_LOCK_CMD, ree_reg.u32);
#else
kc_tee_lock_cmd tee_reg;
if (_ks_is_busy()) {
return SOC_ERR_KS_BUSY;
}
tee_reg.u32 = _ks_read_reg(KC_TEE_LOCK_CMD);
tee_reg.bits.tee_lock_cmd = 0;
tee_reg.bits.tee_tscipher_ind = _ks_is_tscipher(slot_ind);
tee_reg.bits.tee_key_slot_num = slot_num;
_ks_write_reg(KC_TEE_LOCK_CMD, tee_reg.u32);
#endif
return _ks_flush_wait();
}